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
24 #include "coretypes.h"
27 #include "tree-alias-type.h"
29 #include "tree-alias-common.h"
31 /* If we have andersen's points-to analysis, include it. */
33 #include "tree-alias-ander.h"
39 #include "hard-reg-set.h"
40 #include "basic-block.h"
44 #include "diagnostic.h"
47 #include "tree-flow.h"
48 #include "tree-inline.h"
51 #include "tree-gimple.h"
55 #include "tree-pass.h"
58 /* Reduce ifdefery later. */
60 #define HAVE_BANSHEE 0
63 /* This file contains the implementation of the common parts of the
64 tree points-to analysis infrastructure.
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
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. */
80 /* Array of all created alias_vars.
81 Note that this should contain all the alias_vars we wanted
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
90 static GTY(()) varray_type local_alias_vars;
91 static GTY(()) varray_type local_alias_varnums;
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. */
109 call_may_clobber (tree expr)
113 if (TREE_CODE (expr) != CALL_EXPR)
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. */
123 call_may_return (tree expr)
127 if (TREE_CODE (expr) != CALL_EXPR)
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. */
139 get_alias_var_decl (tree decl)
142 gcc_assert (TREE_CODE (decl) != FIELD_DECL);
145 if (DECL_PTA_ALIASVAR (decl))
146 return DECL_PTA_ALIASVAR (decl);
149 if (TREE_CODE (decl) == FUNCTION_DECL)
150 newvar = create_fun_alias_var (decl, 0);
153 newvar = create_alias_var (decl);
154 /* Assign globals to global var for purposes of intraprocedural
156 if (TREE_STATIC (decl) && decl != pta_global_var)
158 current_alias_ops->addr_assign (current_alias_ops,
159 get_alias_var (pta_global_var),
161 /* If the global has some DECL_INITIAL, we need to process
163 if (DECL_INITIAL (decl))
164 find_func_aliases (decl);
168 if (!current_alias_ops->ip)
170 if (!current_alias_ops->ip_partial
171 || (TREE_CODE (decl) != FUNCTION_DECL
172 && TREE_CODE (decl) != PARM_DECL))
174 VARRAY_PUSH_INT (local_alias_varnums, ALIAS_VAR_VARNUM (newvar));
175 VARRAY_PUSH_TREE (local_alias_vars, decl);
181 /* Get the alias_var for an expression EXPR.
182 Note that this function expects to only be handed a RHS or LHS, not
186 get_alias_var (tree expr)
188 /* If it's a decl, get the alias var of the decl. We farm this off
189 to get_alias_var_decl so it can abort if the alias var doesn't
190 exist, and in case something else *knows* it has a decl, and
191 wants the alias var. */
194 return get_alias_var_decl (expr);
196 /* True constants have no aliases (unless modifiable strings are on,
197 in which case i don't think we'll end up with a STRING_CST anyway) */
198 if (TREE_CODE_CLASS (TREE_CODE (expr)) == 'c')
202 switch (TREE_CODE (expr))
205 case ARRAY_RANGE_REF:
207 /* Find the first non-array ref, and return its alias variable. */
211 TREE_CODE (p) == ARRAY_REF || TREE_CODE (p) == ARRAY_RANGE_REF;
212 p = TREE_OPERAND (p, 0))
214 return get_alias_var (p);
223 TREE_CODE (p) == COMPONENT_REF || TREE_CODE (p) == INDIRECT_REF;
224 p = TREE_OPERAND (p, 0))
226 if (TREE_CODE (TREE_TYPE (p)) == UNION_TYPE
227 || TREE_CODE (TREE_TYPE (p)) == QUAL_UNION_TYPE)
235 for (p = expr; TREE_CODE (p) == COMPONENT_REF;
236 p = TREE_OPERAND (p, 0));
237 return get_alias_var (p);
241 return get_alias_var (TREE_OPERAND (expr, 1));
244 /* Find the first non-component ref, and return its alias variable. */
246 for (p = expr; TREE_CODE (p) == COMPONENT_REF;
247 p = TREE_OPERAND (p, 0));
248 return get_alias_var (p);
263 /* If it's a ref or cast or conversion of something, get the
264 alias var of the something. */
265 return get_alias_var (TREE_OPERAND (expr, 0));
273 /* Perform conservative aliasing for an intraprocedural mode function
274 call. ARGS are the arguments that were passed to that function
278 intra_function_call (varray_type args)
280 size_t l = VARRAY_ACTIVE_SIZE (args);
282 alias_var av = get_alias_var (pta_global_var);
284 /* We assume assignments among the actual parameters. */
285 for (i = 0; i < l; i++)
287 alias_var argi = VARRAY_GENERIC_PTR (args, i);
289 for (j = 0; j < l; j++)
294 argj = VARRAY_GENERIC_PTR (args, j);
295 /* Restricted pointers can't be aliased with other
296 restricted pointers. */
297 if (!TYPE_RESTRICT (TREE_TYPE (ALIAS_VAR_DECL (argi)))
298 || !TYPE_RESTRICT (TREE_TYPE (ALIAS_VAR_DECL (argj))))
299 /* Do a bit of TBAA to avoid pointless assignments. */
300 if (alias_sets_conflict_p (get_alias_set (ALIAS_VAR_DECL (argi)),
301 get_alias_set (ALIAS_VAR_DECL (argj))))
302 current_alias_ops->simple_assign (current_alias_ops, argi, argj);
305 /* We assume that an actual parameter can point to any global. */
306 for (i = 0; i < l; i++)
308 alias_var argav = VARRAY_GENERIC_PTR (args, i);
309 /* Restricted pointers can't be aliased with other
310 restricted pointers. */
311 if (!TYPE_RESTRICT (TREE_TYPE (ALIAS_VAR_DECL (argav)))
312 || !TYPE_RESTRICT (TREE_TYPE (ALIAS_VAR_DECL (av))))
314 /* Arguments can alias globals, and whatever they point to
315 can point to a global as well. */
316 current_alias_ops->simple_assign (current_alias_ops, argav, av);
321 /* Put all pointers in a constructor in an array. */
324 get_values_from_constructor (tree constructor, varray_type *vals,
325 bitmap addrargs, int *i)
328 switch (TREE_CODE (constructor))
332 for (elt_list = CONSTRUCTOR_ELTS (constructor);
334 elt_list = TREE_CHAIN (elt_list))
336 tree value = TREE_VALUE (elt_list);
337 if (TREE_CODE (value) == TREE_LIST
338 || TREE_CODE (value) == CONSTRUCTOR)
340 get_values_from_constructor (value, vals, addrargs, i); }
344 aav = get_alias_var (value);
346 VARRAY_PUSH_GENERIC_PTR (*vals, aav);
347 if (TREE_CODE (value) == ADDR_EXPR)
348 bitmap_set_bit (addrargs, *i);
355 for (elt_list = constructor;
357 elt_list = TREE_CHAIN (elt_list))
359 get_values_from_constructor (TREE_VALUE (elt_list), vals, addrargs, i);
367 /* Deal with the possible return values of a call that we don't have
368 actual PTA info about. */
371 deal_with_call_aliasing (tree callargs, alias_var lhsAV)
375 for (argp = callargs;
377 argp = TREE_CHAIN (argp))
379 arg = TREE_VALUE (argp);
380 /* If we take the address of a variable directly in the
381 argument, the return value could be the address of that
383 if (TREE_CODE (arg) == ADDR_EXPR)
384 current_alias_ops->addr_assign (current_alias_ops, lhsAV,
385 get_alias_var (arg));
386 /* If we pass in a pointer, we could return that pointer. */
387 else if (POINTER_TYPE_P (TREE_TYPE (arg)))
389 alias_var argtv = get_alias_var (arg);
391 current_alias_ops->simple_assign (current_alias_ops, lhsAV,
397 /* Find the operand of the component ref that actually is doing
398 something to the DECL */
400 find_op_of_decl (tree cref)
402 while (!DECL_P (TREE_OPERAND (cref, 0)))
404 cref = TREE_OPERAND (cref, 0);
410 /* Tree walker that is the heart of the aliasing infrastructure.
411 TP is a pointer to the current tree.
412 WALK_SUBTREES specifies whether to continue traversing subtrees or
414 Returns NULL_TREE when we should stop.
416 This function is the main part of the aliasing infrastructure. It
417 walks the trees, calling the appropriate alias analyzer functions to process
418 various statements. */
421 find_func_aliases (tree stp)
423 if (TREE_CODE (stp) == RETURN_EXPR)
425 stp = TREE_OPERAND (stp, 0);
430 if (TREE_CODE (stp) == MODIFY_EXPR
431 || (DECL_P (stp) && DECL_INITIAL (stp) != NULL_TREE ))
434 alias_var lhsAV = NULL;
435 alias_var rhsAV = NULL;
440 op1 = DECL_INITIAL (stp);
444 op0 = TREE_OPERAND (stp, 0);
445 op1 = TREE_OPERAND (stp, 1);
446 if (TREE_CODE (op1) == WITH_SIZE_EXPR)
447 op1 = TREE_OPERAND (op1, 0);
450 /* lhsAV should always have an alias variable */
451 lhsAV = get_alias_var (op0);
454 /* rhsAV might not have one, c.f. c = 5 */
455 rhsAV = get_alias_var (op1);
457 while (TREE_CODE (op1) == COMPONENT_REF
458 && TREE_CODE (TREE_OPERAND (op1, 0)) == COMPONENT_REF)
460 op1 = TREE_OPERAND (op1, 0);
462 while (TREE_CODE (op1) == BIT_FIELD_REF)
464 op1 = TREE_OPERAND (op1, 0);
466 /* Take care of fact that we may have multi-level component
468 if (TREE_CODE (op1) == COMPONENT_REF)
469 op1 = find_op_of_decl (op1);
472 /* You would think we could test rhsAV at the top, rather than
473 50 separate times, but we can't, because it can be NULL for
474 operator assignments, where we'd still collect the individual
475 alias vars for the operator. */
477 /* Note that structures are treated as a single alias
478 variable, since we can disambiguate based on TBAA first,
479 and fall back on points-to. */
480 /* x = <something> */
481 if (is_gimple_variable (op0))
484 if (is_gimple_variable (op1))
487 current_alias_ops->simple_assign (current_alias_ops, lhsAV,
491 else if (TREE_CODE (op1) == COMPONENT_REF
492 && DECL_P (TREE_OPERAND (op1, 0)))
495 current_alias_ops->simple_assign (current_alias_ops, lhsAV,
498 /* x = (cast) [maybe-addr-expr] y */
499 else if (is_gimple_cast (op1))
501 tree stripped_op1 = op1;
502 STRIP_NOPS (stripped_op1);
505 if (TREE_CODE (stripped_op1) == ADDR_EXPR)
506 current_alias_ops->addr_assign (current_alias_ops, lhsAV,
509 current_alias_ops->simple_assign (current_alias_ops, lhsAV,
513 /* x = *y or x = foo->y */
514 else if (TREE_CODE (op1) == INDIRECT_REF
515 || TREE_CODE (op1) == ARRAY_REF
516 || (TREE_CODE (op1) == COMPONENT_REF
517 && TREE_CODE (TREE_OPERAND (op1, 0)) == INDIRECT_REF))
520 current_alias_ops->ptr_assign (current_alias_ops, lhsAV,
523 /* x = &y = x = &foo.y */
524 else if (TREE_CODE (op1) == ADDR_EXPR)
527 current_alias_ops->addr_assign (current_alias_ops, lhsAV,
531 else if (TREE_CODE (op1) == CALL_EXPR)
533 /* Heap assignment. These are __attribute__ malloc or
534 something, I'll deal with it later. */
540 /* NORETURN functions have no effect on aliasing. */
541 if (call_may_return (op1))
545 tree callop0, callop1;
548 /* Collect the arguments */
549 VARRAY_GENERIC_PTR_INIT (args, 1, "Arguments");
550 bitmap_clear (addrargs);
551 callop1 = TREE_OPERAND (op1, 1);
552 callop0 = TREE_OPERAND (op1, 0);
553 for (arg = callop1, argnum = 0;
555 arg = TREE_CHAIN (arg), argnum++)
557 alias_var aav = get_alias_var (TREE_VALUE (arg));
560 VARRAY_PUSH_GENERIC_PTR (args, aav);
561 if (TREE_CODE (TREE_VALUE (arg)) == ADDR_EXPR)
562 bitmap_set_bit (addrargs, argnum);
565 /* Simulate the call */
566 if (current_alias_ops->function_call (current_alias_ops, lhsAV,
567 get_alias_var (callop0),
570 if (call_may_clobber (op1)
571 && !current_alias_ops->ip
572 && flag_argument_noalias != 2)
574 intra_function_call (args);
576 if (POINTER_TYPE_P (TREE_TYPE (op0)))
577 deal_with_call_aliasing (callop1, lhsAV);
585 bitmap_clear (addrargs);
586 if (TREE_CODE (op1) == CONSTRUCTOR)
590 VARRAY_GENERIC_PTR_INIT (ops, 1, "Operands");
591 get_values_from_constructor (op1, &ops, addrargs, &i);
592 current_alias_ops->op_assign (current_alias_ops, lhsAV,
596 switch (TREE_CODE_CLASS (TREE_CODE (op1)))
598 case 'e': /* an expression */
599 case 's': /* an expression with side effects */
600 case '<': /* a comparison expression */
601 case '1': /* a unary arithmetic expression */
602 case 'r': /* a reference */
603 case '2': /* a binary arithmetic expression */
608 VARRAY_GENERIC_PTR_INIT (ops, 1, "Operands");
609 for (i = 0; i < TREE_CODE_LENGTH (TREE_CODE (op1)); i++)
612 op = TREE_OPERAND (op1, i);
613 aav = get_alias_var (op);
615 VARRAY_PUSH_GENERIC_PTR (ops, aav);
616 if (TREE_CODE (op) == ADDR_EXPR)
617 bitmap_set_bit (addrargs, i);
619 current_alias_ops->op_assign (current_alias_ops, lhsAV,
628 /* *x = <something> */
631 /* x.f = y or x->f = y */
632 if ((TREE_CODE (op0) == COMPONENT_REF
633 || TREE_CODE (op0) == BIT_FIELD_REF)
634 && is_gimple_variable (op1))
637 current_alias_ops->simple_assign (current_alias_ops, lhsAV,
640 /* x.f = &y or x->f = &y */
641 else if (TREE_CODE (op0) == COMPONENT_REF
642 && TREE_CODE (op1) == ADDR_EXPR)
645 current_alias_ops->addr_assign (current_alias_ops, lhsAV,
648 /* *x.f = y or *x->f = y */
649 else if ((TREE_CODE (op0) == INDIRECT_REF
650 || TREE_CODE (op0) == ARRAY_REF)
651 && TREE_CODE (TREE_OPERAND (op0, 0)) == COMPONENT_REF
652 && is_gimple_variable (op1))
655 current_alias_ops->assign_ptr (current_alias_ops, lhsAV,
659 else if ((TREE_CODE (op0) == INDIRECT_REF
660 || TREE_CODE (op0) == ARRAY_REF)
661 && TREE_CODE (op1) == ADDR_EXPR)
663 /* This becomes temp = &y and *x = temp . */
665 tree temp = create_tmp_var_raw (void_type_node, "aliastmp");
666 tempvar = current_alias_ops->add_var (current_alias_ops, temp);
667 current_alias_ops->addr_assign (current_alias_ops, tempvar,
669 current_alias_ops->assign_ptr (current_alias_ops, lhsAV,
674 else if ((TREE_CODE (op0) == INDIRECT_REF
675 || TREE_CODE (op0) == ARRAY_REF)
676 && (TREE_CODE (op1) == INDIRECT_REF
677 || TREE_CODE (op1) == ARRAY_REF))
679 /* This becomes temp = *y and *x = temp . */
682 temp = create_tmp_var_raw (void_type_node, "aliastmp");
683 tempvar = current_alias_ops->add_var (current_alias_ops, temp);
684 current_alias_ops->ptr_assign (current_alias_ops, tempvar,
686 current_alias_ops->assign_ptr (current_alias_ops, lhsAV,
691 else if ((TREE_CODE (op0) == INDIRECT_REF
692 || TREE_CODE (op0) == ARRAY_REF)
693 && is_gimple_cast (op1))
697 /* This becomes temp = (cast) y and *x = temp. */
700 temp = create_tmp_var_raw (void_type_node, "aliastmp");
701 tempvar = current_alias_ops->add_var (current_alias_ops,
703 current_alias_ops->simple_assign (current_alias_ops,
705 current_alias_ops->assign_ptr (current_alias_ops, lhsAV,
709 /* *x = <something else> */
713 current_alias_ops->assign_ptr (current_alias_ops, lhsAV,
718 /* Calls without return values. */
719 else if (TREE_CODE (stp) == CALL_EXPR)
724 callvar = get_alias_var (TREE_OPERAND (stp, 0));
728 /* NORETURN and CONST functions with no return value
729 have no effect on aliasing (as may be seen above,
730 const functions that return a value might have an
731 effect on aliasing, since the return value can point
732 to one of the arguments. */
733 if (call_may_clobber (stp))
736 VARRAY_GENERIC_PTR_INIT (args, 1, "Arguments");
737 bitmap_clear (addrargs);
738 for (arg = TREE_OPERAND (stp, 1), argnum=0;
740 arg = TREE_CHAIN (arg), argnum++)
742 alias_var aav = get_alias_var (TREE_VALUE (arg));
745 VARRAY_PUSH_GENERIC_PTR (args, aav);
746 if (TREE_CODE (TREE_VALUE (arg)) == ADDR_EXPR)
747 bitmap_set_bit (addrargs, argnum);
752 if (current_alias_ops->function_call (current_alias_ops, NULL,
753 callvar, args, addrargs))
754 if (!current_alias_ops->ip && flag_argument_noalias != 2)
755 intra_function_call (args);
761 /* Create the alias_var for a function definition DECL, it's
762 arguments, and it's return value. If FORCE is true, we force
763 creation of the alias_var, regardless of whether one exists already.
765 This includes creation of alias_var's for
766 - The function itself.
768 - The return value. */
771 create_fun_alias_var (tree decl, int force)
773 alias_var avar, retvar;
775 varray_type params = NULL;
779 if (DECL_PTA_ALIASVAR (decl))
780 return DECL_PTA_ALIASVAR (decl);
783 VARRAY_GENERIC_PTR_INIT (params, 1, "Arguments");
784 if (DECL_ARGUMENTS (decl) != NULL)
787 for (arg = DECL_ARGUMENTS (decl); arg; arg = TREE_CHAIN (arg))
789 alias_var var = get_alias_var (arg);
790 VARRAY_PUSH_GENERIC_PTR (params, var);
791 /* Incoming pointers can point to pta_global_var, unless
792 either we are interprocedural, or we can do ip on all
793 statics + this function has been defined + it's not an
794 external function. */
795 if (POINTER_TYPE_P (TREE_TYPE (arg))
796 && !current_alias_ops->ip
797 /* FIXME: Need to let analyzer decide in partial case. */
798 && (!current_alias_ops->ip_partial
799 || !cgraph_local_info (decl)->local))
800 current_alias_ops->simple_assign (current_alias_ops, var,
801 get_alias_var (pta_global_var));
804 else if (TYPE_ARG_TYPES (TREE_TYPE (decl)) != NULL)
807 /* FIXME: Handle varargs */
808 for (arg = TYPE_ARG_TYPES (TREE_TYPE (decl));
809 arg && TREE_VALUE (arg) != void_type_node;
810 arg = TREE_CHAIN (arg))
812 tree fakedecl = create_tmp_var_raw (TREE_VALUE (arg), "normarg");
814 DECL_CONTEXT (fakedecl) = current_function_decl;
815 var = get_alias_var (fakedecl);
816 VARRAY_PUSH_GENERIC_PTR (params, var);
818 /* Incoming pointers can point to pta_global_var, unless
819 either we are interprocedural, or we can do ip on all
820 statics + this function has been defined + it's not an
821 external function. */
822 if (POINTER_TYPE_P (TREE_TYPE (fakedecl))
823 && !current_alias_ops->ip
824 /* FIXME: need to let analyzer decide in partial case. */
825 && (!current_alias_ops->ip_partial
826 || !TREE_STATIC (decl)
827 || TREE_PUBLIC (decl)))
828 current_alias_ops->simple_assign (current_alias_ops, var,
829 get_alias_var (pta_global_var));
832 /* Functions declared like void f() are *not* equivalent to void
833 f(void). You can pass an argument to them. Thus, we need to
834 create some fake argument that would alias any actuals that get
835 passed to our function. */
838 tree fakedecl = create_tmp_var_raw (void_type_node, "fakearg");
840 DECL_CONTEXT (fakedecl) = current_function_decl;
841 fakevar = get_alias_var (fakedecl);
842 VARRAY_PUSH_GENERIC_PTR (params, fakevar);
845 if (!DECL_RESULT (decl))
847 rdecl = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (decl)), "_rv_");
848 retvar = current_alias_ops->add_var (current_alias_ops, rdecl);
849 DECL_PTA_ALIASVAR (rdecl) = retvar;
853 retvar = current_alias_ops->add_var (current_alias_ops,
855 DECL_PTA_ALIASVAR (DECL_RESULT (decl)) = retvar;
857 VARRAY_PUSH_GENERIC_PTR (alias_vars, retvar);
858 ALIAS_VAR_VARNUM (retvar) = VARRAY_ACTIVE_SIZE (alias_vars) - 1;
859 avar = current_alias_ops->add_var (current_alias_ops, decl);
860 VARRAY_PUSH_GENERIC_PTR (alias_vars, avar);
861 ALIAS_VAR_VARNUM (avar) = VARRAY_ACTIVE_SIZE (alias_vars) - 1;
863 current_alias_ops->function_def (current_alias_ops, avar, params, retvar);
864 DECL_PTA_ALIASVAR (decl) = avar;
866 /* FIXME: Also, if this is a defining declaration then add the annotation
867 to all extern definitions of the function. */
871 /* Create an alias variable for a pointer-to-member function DECL of
872 type TYPE, it's arguments, and it's return value.
873 Returns the alias_var for the PTF.
875 This includes creating alias_var's for
876 - The function itself.
878 - The return value. */
881 create_fun_alias_var_ptf (tree decl, tree type)
883 alias_var avar, retvar;
885 varray_type params = NULL;
887 if (DECL_PTA_ALIASVAR (decl))
888 return DECL_PTA_ALIASVAR (decl);
890 VARRAY_GENERIC_PTR_INIT (params, 1, "Arguments");
892 if (TYPE_ARG_TYPES (type) != NULL)
895 /* FIXME: Handle varargs */
896 for (arg = TYPE_ARG_TYPES (type);
897 arg && TREE_VALUE (arg) != void_type_node;
898 arg = TREE_CHAIN (arg))
900 tree fakedecl = create_tmp_var_raw (TREE_VALUE (arg), "ptfarg");
902 DECL_CONTEXT (fakedecl) = DECL_CONTEXT (decl);
903 var = get_alias_var (fakedecl);
904 VARRAY_PUSH_GENERIC_PTR (params, var);
907 /* Functions declared like void f() are *not* equivalent to void
908 f(void). You can pass an argument to them. Thus, we need to
909 create some fake argument that would alias any actuals that get
910 passed to our function. */
913 tree fakedecl = create_tmp_var_raw (void_type_node, "fakearg");
915 DECL_CONTEXT (fakedecl) = DECL_CONTEXT (decl);
916 fakevar = get_alias_var (fakedecl);
917 VARRAY_PUSH_GENERIC_PTR (params, fakevar);
920 rdecl = create_tmp_var_raw (TREE_TYPE (type), "_rv_");
921 retvar = current_alias_ops->add_var (current_alias_ops, rdecl);
922 VARRAY_PUSH_GENERIC_PTR (alias_vars, retvar);
923 ALIAS_VAR_VARNUM (retvar) = VARRAY_ACTIVE_SIZE (alias_vars) - 1;
925 avar = current_alias_ops->add_var (current_alias_ops, decl);
926 VARRAY_PUSH_GENERIC_PTR (alias_vars, avar);
927 ALIAS_VAR_VARNUM (avar) = VARRAY_ACTIVE_SIZE (alias_vars) - 1;
929 current_alias_ops->function_def (current_alias_ops, avar, params, retvar);
930 DECL_PTA_ALIASVAR (decl) = avar;
935 /* Create the alias_var for a *_DECL node DECL.
936 Returns the alias_var for DECL.
938 This function also handles creation of alias_var's for PTF
942 create_alias_var (tree decl)
946 gcc_assert (DECL_P (decl));
948 if (DECL_PTA_ALIASVAR (decl))
949 return DECL_PTA_ALIASVAR (decl);
951 if (POINTER_TYPE_P (TREE_TYPE (decl))
952 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == FUNCTION_TYPE)
954 avar = create_fun_alias_var_ptf (decl, TREE_TYPE (TREE_TYPE (decl)));
957 avar = current_alias_ops->add_var (current_alias_ops, decl);
961 DECL_PTA_ALIASVAR (decl) = avar;
964 VARRAY_PUSH_GENERIC_PTR (alias_vars, avar);
965 ALIAS_VAR_VARNUM (avar) = VARRAY_ACTIVE_SIZE (alias_vars) - 1;
969 /* Create points-to sets for the current function. */
972 create_alias_vars (void)
976 if (flag_tree_points_to == PTA_ANDERSEN)
977 current_alias_ops = andersen_alias_ops;
981 current_alias_ops = NULL;
982 flag_tree_points_to = PTA_NONE;
986 pta_global_var = build_decl (VAR_DECL, get_identifier (".pta_global_var"),
988 DECL_ARTIFICIAL (pta_global_var) = 1;
989 TREE_READONLY (pta_global_var) = 1;
990 DECL_EXTERNAL (pta_global_var) = 0;
991 TREE_STATIC (pta_global_var) = 1;
992 TREE_USED (pta_global_var) = 1;
993 DECL_CONTEXT (pta_global_var) = current_function_decl;
994 TREE_THIS_VOLATILE (pta_global_var) = 1;
995 TREE_ADDRESSABLE (pta_global_var) = 0;
999 DECL_PTA_ALIASVAR (current_function_decl) = NULL;
1000 get_alias_var (current_function_decl);
1002 /* First, walk the variables and their DECL_INITIAL's */
1003 if (cfun->unexpanded_var_list)
1006 for (vars = cfun->unexpanded_var_list; vars; vars = TREE_CHAIN (vars))
1008 var = TREE_VALUE (vars);
1009 if (TREE_CODE (var) != LABEL_DECL
1010 && TREE_STATIC (var)
1011 && DECL_INITIAL (var))
1012 find_func_aliases (var);
1016 /* Now walk all statements and derive aliases. */
1019 block_stmt_iterator bsi;
1020 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
1021 find_func_aliases (bsi_stmt (bsi));
1024 pta_global_var = NULL_TREE;
1031 return flag_tree_points_to != PTA_NONE;
1037 struct tree_opt_pass pass_build_pta =
1040 gate_pta, /* gate */
1041 create_alias_vars, /* execute */
1044 0, /* static_pass_number */
1045 TV_TREE_PTA, /* tv_id */
1046 PROP_cfg, /* properties_required */
1047 PROP_pta, /* properties_provided */
1048 0, /* properties_destroyed */
1049 0, /* todo_flags_start */
1050 0, /* todo_flags_finish */
1055 /* Delete created points-to sets. */
1058 delete_alias_vars (void)
1062 for (i = 0; i < VARRAY_ACTIVE_SIZE (local_alias_vars); i++)
1064 tree key = VARRAY_TREE (local_alias_vars, i);
1065 gcc_assert (DECL_P (key));
1066 DECL_PTA_ALIASVAR (key) = NULL;
1069 for (i = 0; i < VARRAY_ACTIVE_SIZE (local_alias_varnums); i ++)
1070 VARRAY_GENERIC_PTR (alias_vars, VARRAY_INT (local_alias_varnums, i)) = NULL;
1071 if (!current_alias_ops->ip && !current_alias_ops->ip_partial)
1073 /* VARRAY_CLEAR (alias_vars); */
1074 VARRAY_CLEAR (local_alias_vars);
1075 VARRAY_CLEAR (local_alias_varnums);
1077 BITMAP_XFREE (addrargs);
1078 current_alias_ops->cleanup (current_alias_ops);
1081 struct tree_opt_pass pass_del_pta =
1084 gate_pta, /* gate */
1085 delete_alias_vars, /* execute */
1088 0, /* static_pass_number */
1089 TV_TREE_PTA, /* tv_id */
1090 PROP_pta, /* properties_required */
1091 0, /* properties_provided */
1092 PROP_pta, /* properties_destroyed */
1093 0, /* todo_flags_start */
1094 0, /* todo_flags_finish */
1099 /* Initialize points-to analysis machinery. */
1102 init_alias_vars (void)
1104 current_alias_ops->init (current_alias_ops);
1105 addrargs = BITMAP_XMALLOC ();
1106 VARRAY_TREE_INIT (local_alias_vars, 10, "Local alias vars");
1107 VARRAY_INT_INIT (local_alias_varnums, 10, "Local alias varnums");
1108 if ((!current_alias_ops->ip && !current_alias_ops->ip_partial)
1109 || alias_vars == NULL)
1110 VARRAY_GENERIC_PTR_INIT (alias_vars, 10, "Alias vars");
1113 /* Return true if PTR can't point to anything (i.e. it has an empty
1116 empty_points_to_set (tree ptr)
1122 if (TREE_CODE (ptr) == COMPONENT_REF)
1123 ptr = TREE_OPERAND (ptr, 1);
1126 gcc_assert (DECL_P (ptr));
1127 ptrtv = DECL_PTA_ALIASVAR (ptr);
1131 return current_alias_ops->empty_points_to_set (current_alias_ops, ptrtv);
1134 /* Return true if PTR and VAR have the same points-to set. */
1137 same_points_to_set (tree ptr, tree var)
1139 alias_var ptrtv, vartv;
1143 if (TREE_CODE (ptr) == COMPONENT_REF)
1144 ptr = TREE_OPERAND (ptr, 1);
1145 if (TREE_CODE (var) == COMPONENT_REF)
1146 var = TREE_OPERAND (var, 1);
1152 gcc_assert (DECL_P (ptr));
1153 ptrtv = DECL_PTA_ALIASVAR (ptr);
1157 gcc_assert (DECL_P (var));
1158 vartv = DECL_PTA_ALIASVAR (var);
1162 return current_alias_ops->same_points_to_set (current_alias_ops, vartv, ptrtv);
1165 /* Determine whether two variables (PTR and VAR) may-alias.
1166 Returns TRUE if PTR may-alias VAR. */
1169 ptr_may_alias_var (tree ptr, tree var)
1171 alias_var ptrtv, vartv;
1175 if (TREE_CODE (ptr) == COMPONENT_REF)
1176 ptr = TREE_OPERAND (ptr, 1);
1177 if (TREE_CODE (var) == COMPONENT_REF)
1178 var = TREE_OPERAND (var, 1);
1184 gcc_assert (DECL_P (ptr));
1185 ptrtv = DECL_PTA_ALIASVAR (ptr);
1189 gcc_assert (DECL_P (var));
1190 vartv = DECL_PTA_ALIASVAR (var);
1194 return current_alias_ops->may_alias (current_alias_ops, ptrtv, vartv);
1197 #define MASK_POINTER(P) ((unsigned)((unsigned long)(P) & 0xffff))
1200 alias_get_name (tree t)
1205 if (TREE_CODE (t) == FIELD_DECL)
1207 /* First get the name of the field, then the prefix, then smash them
1209 const char *fieldname = IDENTIFIER_POINTER (DECL_NAME (t));
1210 const char *prefix = alias_get_name (DECL_CONTEXT (t));
1212 size_t neededlen = strlen (fieldname) + strlen (prefix) + 2;
1213 smashed = ggc_alloc (neededlen);
1214 sprintf (smashed, "%s.%s", prefix, fieldname);
1218 else if (TYPE_P (t))
1220 if (TYPE_NAME (t) && IDENTIFIER_POINTER (TYPE_NAME (t)))
1221 name = IDENTIFIER_POINTER (TYPE_NAME (t));
1223 name = "<unnamed type>";
1228 if (TREE_CODE (t) == FUNCTION_DECL)
1229 name = IDENTIFIER_POINTER (DECL_NAME (t));
1230 else if (TREE_CODE (t) == RESULT_DECL)
1231 name = "<return value>";
1233 name = get_name (t);
1240 4 = the masked pointer
1241 2 = the <> around it
1242 1 = the terminator. */
1243 namep = ggc_alloc (2 + 4 + 2 + 1);
1244 sprintf (namep, "<UV%x>", MASK_POINTER (t));
1251 #include "gt-tree-alias-common.h"