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
23 #include "coretypes.h"
26 #include "tree-alias-type.h"
28 #include "tree-alias-common.h"
29 /* If we have andersen's points-to analysis, include it. */
31 #include "tree-alias-ander.h"
36 #include "hard-reg-set.h"
37 #include "basic-block.h"
41 #include "diagnostic.h"
44 #include "tree-flow.h"
45 #include "tree-inline.h"
48 #include "tree-gimple.h"
52 #include "tree-pass.h"
55 /* Reduce ifdefery later. */
57 #define HAVE_BANSHEE 0
60 /* This file contains the implementation of the common parts of the
61 tree points-to analysis infrastructure.
65 This file contains the points-to analysis driver. It does two main things:
66 1. Keeps track of the PTA data for each variable (IE the data each
67 specific PTA implementation wants to keep associated with a
69 2. Walks the function trees, calling the appropriate functions that
70 each PTA implementation has implemented.
72 In order to speed up PTA queries, the PTA specific data is stored
73 in the tree for *_DECL's, in DECL_PTA_ALIASVAR. This way, we only
74 need to use the hash table for non-DECL's. */
77 /* Array of all created alias_vars.
78 Note that this should contain all the alias_vars we wanted
80 static GTY((param_is (union alias_var_def
))) varray_type alias_vars
= NULL
;
81 struct tree_alias_ops
*current_alias_ops
;
83 /* Array of local (to a function) alias_vars.
84 Note that this should contain all the alias_vars that are
85 local to this function. We delete these from alias_vars before
87 static GTY(()) varray_type local_alias_vars
;
88 static GTY(()) varray_type local_alias_varnums
;
90 static bitmap addrargs
;
91 static alias_var
get_alias_var_decl (tree
);
92 static alias_var
get_alias_var (tree
);
93 static void find_func_aliases (tree
);
94 static void deal_with_call_aliasing (tree
, alias_var
);
95 static alias_var
create_fun_alias_var_ptf (tree
, tree
);
96 static alias_var
create_fun_alias_var (tree
, int);
97 static alias_var
create_alias_var (tree
);
98 static void intra_function_call (varray_type
);
99 static void get_values_from_constructor (tree
, varray_type
*, bitmap
, int *);
100 static bool call_may_clobber (tree
);
101 static bool call_may_return (tree
);
103 /* Return true if a EXPR, which is a CALL_EXPR, may clobber variables. */
106 call_may_clobber (tree expr
)
110 if (TREE_CODE (expr
) != CALL_EXPR
)
113 flags
= call_expr_flags (expr
);
114 return (! (flags
& (ECF_CONST
| ECF_PURE
| ECF_NORETURN
)));
117 /* Return true if a EXPR, which is a CALL_EXPR, may return. */
120 call_may_return (tree expr
)
124 if (TREE_CODE (expr
) != CALL_EXPR
)
127 flags
= call_expr_flags (expr
);
128 return ! (flags
& ECF_NORETURN
);
131 /* Get the alias_var for DECL.
132 Creates the alias_var if it does not exist already. Also
133 handles FUNCTION_DECL properly. */
136 get_alias_var_decl (tree decl
)
139 if (TREE_CODE (decl
) == FIELD_DECL
)
143 if (DECL_PTA_ALIASVAR (decl
))
144 return DECL_PTA_ALIASVAR (decl
);
147 if (TREE_CODE (decl
) == FUNCTION_DECL
)
148 newvar
= create_fun_alias_var (decl
, 0);
151 newvar
= create_alias_var (decl
);
152 /* Assign globals to global var for purposes of intraprocedural
154 if ((DECL_CONTEXT (decl
) == NULL
155 || TREE_PUBLIC (decl
)
156 || TREE_STATIC (decl
)
157 || decl_function_context (decl
) == NULL
)
158 && decl
!= pta_global_var
)
160 current_alias_ops
->addr_assign (current_alias_ops
,
161 get_alias_var (pta_global_var
),
163 /* If the global has some DECL_INITIAL, we need to process
165 if (DECL_INITIAL (decl
))
166 find_func_aliases (decl
);
170 if (!current_alias_ops
->ip
)
172 if (!current_alias_ops
->ip_partial
173 || (TREE_CODE (decl
) != FUNCTION_DECL
174 && TREE_CODE (decl
) != PARM_DECL
))
176 VARRAY_PUSH_INT (local_alias_varnums
, ALIAS_VAR_VARNUM (newvar
));
177 VARRAY_PUSH_TREE (local_alias_vars
, decl
);
183 /* Get the alias_var for an expression EXPR.
184 Note that this function expects to only be handed a RHS or LHS, not
188 get_alias_var (tree expr
)
190 /* If it's a decl, get the alias var of the decl. We farm this off
191 to get_alias_var_decl so it can abort if the alias var doesn't
192 exist, and in case something else *knows* it has a decl, and
193 wants the alias var. */
196 return get_alias_var_decl (expr
);
198 /* True constants have no aliases (unless modifiable strings are on,
199 in which case i don't think we'll end up with a STRING_CST anyway) */
200 if (TREE_CODE_CLASS (TREE_CODE (expr
)) == 'c')
204 switch (TREE_CODE (expr
))
208 /* Find the first non-array ref, and return it's alias
211 for (p
= expr
; TREE_CODE (p
) == ARRAY_REF
;
212 p
= TREE_OPERAND (p
, 0));
213 return get_alias_var (p
);
222 TREE_CODE (p
) == COMPONENT_REF
|| TREE_CODE (p
) == INDIRECT_REF
;
223 p
= TREE_OPERAND (p
, 0))
225 if (TREE_CODE (TREE_TYPE (p
)) == UNION_TYPE
226 || TREE_CODE (TREE_TYPE (p
)) == QUAL_UNION_TYPE
)
234 for (p
= expr
; TREE_CODE (p
) == COMPONENT_REF
;
235 p
= TREE_OPERAND (p
, 0));
236 return get_alias_var (p
);
240 return get_alias_var (TREE_OPERAND (expr
, 1));
243 /* Find the first non-component ref, and return its alias variable. */
245 for (p
= expr
; TREE_CODE (p
) == COMPONENT_REF
;
246 p
= TREE_OPERAND (p
, 0));
247 return get_alias_var (p
);
262 /* If it's a ref or cast or conversion of something, get the
263 alias var of the something. */
264 return get_alias_var (TREE_OPERAND (expr
, 0));
272 /* Perform conservative aliasing for an intraprocedural mode function
273 call. ARGS are the arguments that were passed to that function
277 intra_function_call (varray_type args
)
279 size_t l
= VARRAY_ACTIVE_SIZE (args
);
281 alias_var av
= get_alias_var (pta_global_var
);
283 /* We assume assignments among the actual parameters. */
284 for (i
= 0; i
< l
; i
++)
286 alias_var argi
= VARRAY_GENERIC_PTR (args
, i
);
288 for (j
= 0; j
< l
; j
++)
293 argj
= VARRAY_GENERIC_PTR (args
, j
);
294 /* Restricted pointers can't be aliased with other
295 restricted pointers. */
296 if (!TYPE_RESTRICT (TREE_TYPE (ALIAS_VAR_DECL (argi
)))
297 || !TYPE_RESTRICT (TREE_TYPE (ALIAS_VAR_DECL (argj
))))
298 /* Do a bit of TBAA to avoid pointless assignments. */
299 if (alias_sets_conflict_p (get_alias_set (ALIAS_VAR_DECL (argi
)),
300 get_alias_set (ALIAS_VAR_DECL (argj
))))
301 current_alias_ops
->simple_assign (current_alias_ops
, argi
, argj
);
304 /* We assume that an actual parameter can point to any global. */
305 for (i
= 0; i
< l
; i
++)
307 alias_var argav
= VARRAY_GENERIC_PTR (args
, i
);
308 /* Restricted pointers can't be aliased with other
309 restricted pointers. */
310 if (!TYPE_RESTRICT (TREE_TYPE (ALIAS_VAR_DECL (argav
)))
311 || !TYPE_RESTRICT (TREE_TYPE (ALIAS_VAR_DECL (av
))))
313 /* Arguments can alias globals, and whatever they point to
314 can point to a global as well. */
315 current_alias_ops
->simple_assign (current_alias_ops
, argav
, av
);
320 /* Put all pointers in a constructor in an array. */
323 get_values_from_constructor (tree constructor
, varray_type
*vals
,
324 bitmap addrargs
, int *i
)
327 switch (TREE_CODE (constructor
))
331 for (elt_list
= CONSTRUCTOR_ELTS (constructor
);
333 elt_list
= TREE_CHAIN (elt_list
))
335 tree value
= TREE_VALUE (elt_list
);
336 if (TREE_CODE (value
) == TREE_LIST
337 || TREE_CODE (value
) == CONSTRUCTOR
)
339 get_values_from_constructor (value
, vals
, addrargs
, i
); }
343 aav
= get_alias_var (value
);
345 VARRAY_PUSH_GENERIC_PTR (*vals
, aav
);
346 if (TREE_CODE (value
) == ADDR_EXPR
)
347 bitmap_set_bit (addrargs
, *i
);
354 for (elt_list
= constructor
;
356 elt_list
= TREE_CHAIN (elt_list
))
358 get_values_from_constructor (TREE_VALUE (elt_list
), vals
, addrargs
, i
);
366 /* Deal with the possible return values of a call that we don't have
367 actual PTA info about. */
370 deal_with_call_aliasing (tree callargs
, alias_var lhsAV
)
374 for (argp
= callargs
;
376 argp
= TREE_CHAIN (argp
))
378 arg
= TREE_VALUE (argp
);
379 /* If we take the address of a variable directly in the
380 argument, the return value could be the address of that
382 if (TREE_CODE (arg
) == ADDR_EXPR
)
383 current_alias_ops
->addr_assign (current_alias_ops
, lhsAV
,
384 get_alias_var (arg
));
385 /* If we pass in a pointer, we could return that pointer. */
386 else if (POINTER_TYPE_P (TREE_TYPE (arg
)))
388 alias_var argtv
= get_alias_var (arg
);
390 current_alias_ops
->simple_assign (current_alias_ops
, lhsAV
,
396 /* Find the operand of the component ref that actually is doing
397 something to the DECL */
399 find_op_of_decl (tree cref
)
401 while (!DECL_P (TREE_OPERAND (cref
, 0)))
403 cref
= TREE_OPERAND (cref
, 0);
409 /* Tree walker that is the heart of the aliasing infrastructure.
410 TP is a pointer to the current tree.
411 WALK_SUBTREES specifies whether to continue traversing subtrees or
413 Returns NULL_TREE when we should stop.
415 This function is the main part of the aliasing infrastructure. It
416 walks the trees, calling the appropriate alias analyzer functions to process
417 various statements. */
420 find_func_aliases (tree stp
)
422 if (TREE_CODE (stp
) == RETURN_EXPR
)
424 stp
= TREE_OPERAND (stp
, 0);
429 if (TREE_CODE (stp
) == MODIFY_EXPR
430 || (DECL_P (stp
) && DECL_INITIAL (stp
) != NULL_TREE
))
433 alias_var lhsAV
= NULL
;
434 alias_var rhsAV
= NULL
;
439 op1
= DECL_INITIAL (stp
);
443 op0
= TREE_OPERAND (stp
, 0);
444 op1
= TREE_OPERAND (stp
, 1);
446 /* lhsAV should always have an alias variable */
447 lhsAV
= get_alias_var (op0
);
450 /* rhsAV might not have one, c.f. c = 5 */
451 rhsAV
= get_alias_var (op1
);
453 while (TREE_CODE (op1
) == COMPONENT_REF
454 && TREE_CODE (TREE_OPERAND (op1
, 0)) == COMPONENT_REF
)
456 op1
= TREE_OPERAND (op1
, 0);
458 while (TREE_CODE (op1
) == BIT_FIELD_REF
)
460 op1
= TREE_OPERAND (op1
, 0);
462 /* Take care of fact that we may have multi-level component
464 if (TREE_CODE (op1
) == COMPONENT_REF
)
465 op1
= find_op_of_decl (op1
);
468 /* You would think we could test rhsAV at the top, rather than
469 50 separate times, but we can't, because it can be NULL for
470 operator assignments, where we'd still collect the individual
471 alias vars for the operator. */
473 /* Note that structures are treated as a single alias
474 variable, since we can disambiguate based on TBAA first,
475 and fall back on points-to. */
476 /* x = <something> */
477 if (is_gimple_variable (op0
))
480 if (is_gimple_variable (op1
))
483 current_alias_ops
->simple_assign (current_alias_ops
, lhsAV
,
487 else if (TREE_CODE (op1
) == COMPONENT_REF
488 && DECL_P (TREE_OPERAND (op1
, 0)))
491 current_alias_ops
->simple_assign (current_alias_ops
, lhsAV
,
494 /* x = (cast) [maybe-addr-expr] y */
495 else if (is_gimple_cast (op1
))
497 tree stripped_op1
= op1
;
498 STRIP_NOPS (stripped_op1
);
501 if (TREE_CODE (stripped_op1
) == ADDR_EXPR
)
502 current_alias_ops
->addr_assign (current_alias_ops
, lhsAV
,
505 current_alias_ops
->simple_assign (current_alias_ops
, lhsAV
,
509 /* x = *y or x = foo->y */
510 else if (TREE_CODE (op1
) == INDIRECT_REF
511 || TREE_CODE (op1
) == ARRAY_REF
512 || (TREE_CODE (op1
) == COMPONENT_REF
513 && TREE_CODE (TREE_OPERAND (op1
, 0)) == INDIRECT_REF
))
516 current_alias_ops
->ptr_assign (current_alias_ops
, lhsAV
,
519 /* x = &y = x = &foo.y */
520 else if (TREE_CODE (op1
) == ADDR_EXPR
)
523 current_alias_ops
->addr_assign (current_alias_ops
, lhsAV
,
527 else if (TREE_CODE (op1
) == CALL_EXPR
)
529 /* Heap assignment. These are __attribute__ malloc or
530 something, i'll deal with it later. */
536 /* NORETURN functions have no effect on aliasing. */
537 if (call_may_return (op1
))
541 tree callop0
, callop1
;
544 /* Collect the arguments */
545 VARRAY_GENERIC_PTR_INIT (args
, 1, "Arguments");
546 bitmap_clear (addrargs
);
547 callop1
= TREE_OPERAND (op1
, 1);
548 callop0
= TREE_OPERAND (op1
, 0);
549 for (arg
= callop1
, argnum
= 0;
551 arg
= TREE_CHAIN (arg
), argnum
++)
553 alias_var aav
= get_alias_var (TREE_VALUE (arg
));
556 VARRAY_PUSH_GENERIC_PTR (args
, aav
);
557 if (TREE_CODE (TREE_VALUE (arg
)) == ADDR_EXPR
)
558 bitmap_set_bit (addrargs
, argnum
);
561 /* Simulate the call */
562 if (current_alias_ops
->function_call (current_alias_ops
, lhsAV
,
563 get_alias_var (callop0
),
566 if (call_may_clobber (op1
)
567 && !current_alias_ops
->ip
568 && flag_argument_noalias
!= 2)
570 intra_function_call (args
);
572 if (POINTER_TYPE_P (TREE_TYPE (op0
)))
573 deal_with_call_aliasing (callop1
, lhsAV
);
581 bitmap_clear (addrargs
);
582 if (TREE_CODE (op1
) == CONSTRUCTOR
)
586 VARRAY_GENERIC_PTR_INIT (ops
, 1, "Operands");
587 get_values_from_constructor (op1
, &ops
, addrargs
, &i
);
588 current_alias_ops
->op_assign (current_alias_ops
, lhsAV
,
592 switch (TREE_CODE_CLASS (TREE_CODE (op1
)))
594 case 'e': /* an expression */
595 case 's': /* an expression with side effects */
596 case '<': /* a comparison expression */
597 case '1': /* a unary arithmetic expression */
598 case 'r': /* a reference */
599 case '2': /* a binary arithmetic expression */
604 VARRAY_GENERIC_PTR_INIT (ops
, 1, "Operands");
605 for (i
= 0; i
< TREE_CODE_LENGTH (TREE_CODE (op1
)); i
++)
608 op
= TREE_OPERAND (op1
, i
);
609 aav
= get_alias_var (op
);
611 VARRAY_PUSH_GENERIC_PTR (ops
, aav
);
612 if (TREE_CODE (op
) == ADDR_EXPR
)
613 bitmap_set_bit (addrargs
, i
);
615 current_alias_ops
->op_assign (current_alias_ops
, lhsAV
,
624 /* *x = <something> */
627 /* x.f = y or x->f = y */
628 if ((TREE_CODE (op0
) == COMPONENT_REF
629 || TREE_CODE (op0
) == BIT_FIELD_REF
)
630 && is_gimple_variable (op1
))
633 current_alias_ops
->simple_assign (current_alias_ops
, lhsAV
,
636 /* x.f = &y or x->f = &y */
637 else if (TREE_CODE (op0
) == COMPONENT_REF
638 && TREE_CODE (op1
) == ADDR_EXPR
)
641 current_alias_ops
->addr_assign (current_alias_ops
, lhsAV
,
644 /* *x.f = y or *x->f = y */
645 else if ((TREE_CODE (op0
) == INDIRECT_REF
646 || TREE_CODE (op0
) == ARRAY_REF
)
647 && TREE_CODE (TREE_OPERAND (op0
, 0)) == COMPONENT_REF
648 && is_gimple_variable (op1
))
651 current_alias_ops
->assign_ptr (current_alias_ops
, lhsAV
,
655 else if ((TREE_CODE (op0
) == INDIRECT_REF
656 || TREE_CODE (op0
) == ARRAY_REF
)
657 && TREE_CODE (op1
) == ADDR_EXPR
)
659 /* This becomes temp = &y and *x = temp . */
661 tree temp
= create_tmp_var_raw (void_type_node
, "aliastmp");
662 tempvar
= current_alias_ops
->add_var (current_alias_ops
, temp
);
663 current_alias_ops
->addr_assign (current_alias_ops
, tempvar
,
665 current_alias_ops
->assign_ptr (current_alias_ops
, lhsAV
,
670 else if ((TREE_CODE (op0
) == INDIRECT_REF
671 || TREE_CODE (op0
) == ARRAY_REF
)
672 && (TREE_CODE (op1
) == INDIRECT_REF
673 || TREE_CODE (op1
) == ARRAY_REF
))
675 /* This becomes temp = *y and *x = temp . */
678 temp
= create_tmp_var_raw (void_type_node
, "aliastmp");
679 tempvar
= current_alias_ops
->add_var (current_alias_ops
, temp
);
680 current_alias_ops
->ptr_assign (current_alias_ops
, tempvar
,
682 current_alias_ops
->assign_ptr (current_alias_ops
, lhsAV
,
687 else if ((TREE_CODE (op0
) == INDIRECT_REF
688 || TREE_CODE (op0
) == ARRAY_REF
)
689 && is_gimple_cast (op1
))
693 /* This becomes temp = (cast) y and *x = temp. */
696 temp
= create_tmp_var_raw (void_type_node
, "aliastmp");
697 tempvar
= current_alias_ops
->add_var (current_alias_ops
,
699 current_alias_ops
->simple_assign (current_alias_ops
,
701 current_alias_ops
->assign_ptr (current_alias_ops
, lhsAV
,
705 /* *x = <something else> */
709 current_alias_ops
->assign_ptr (current_alias_ops
, lhsAV
,
714 /* Calls without return values. */
715 else if (TREE_CODE (stp
) == CALL_EXPR
)
720 callvar
= get_alias_var (TREE_OPERAND (stp
, 0));
724 /* NORETURN and CONST functions with no return value
725 have no effect on aliasing (as may be seen above,
726 const functions that return a value might have an
727 effect on aliasing, since the return value can point
728 to one of the arguments. */
729 if (call_may_clobber (stp
))
732 VARRAY_GENERIC_PTR_INIT (args
, 1, "Arguments");
733 bitmap_clear (addrargs
);
734 for (arg
= TREE_OPERAND (stp
, 1), argnum
=0;
736 arg
= TREE_CHAIN (arg
), argnum
++)
738 alias_var aav
= get_alias_var (TREE_VALUE (arg
));
741 VARRAY_PUSH_GENERIC_PTR (args
, aav
);
742 if (TREE_CODE (TREE_VALUE (arg
)) == ADDR_EXPR
)
743 bitmap_set_bit (addrargs
, argnum
);
748 if (current_alias_ops
->function_call (current_alias_ops
, NULL
,
749 callvar
, args
, addrargs
))
750 if (!current_alias_ops
->ip
&& flag_argument_noalias
!= 2)
751 intra_function_call (args
);
757 /* Create the alias_var for a function definition DECL, it's
758 arguments, and it's return value. If FORCE is true, we force
759 creation of the alias_var, regardless of whether one exists already.
761 This includes creation of alias_var's for
762 - The function itself.
764 - The return value. */
767 create_fun_alias_var (tree decl
, int force
)
769 alias_var avar
, retvar
;
771 varray_type params
= NULL
;
775 if (DECL_PTA_ALIASVAR (decl
))
776 return DECL_PTA_ALIASVAR (decl
);
779 VARRAY_GENERIC_PTR_INIT (params
, 1, "Arguments");
780 if (DECL_ARGUMENTS (decl
) != NULL
)
783 for (arg
= DECL_ARGUMENTS (decl
); arg
; arg
= TREE_CHAIN (arg
))
785 alias_var var
= get_alias_var (arg
);
786 VARRAY_PUSH_GENERIC_PTR (params
, var
);
787 /* Incoming pointers can point to pta_global_var, unless
788 either we are interprocedural, or we can do ip on all
789 statics + this function has been defined + it's not an
790 external function. */
791 if (POINTER_TYPE_P (TREE_TYPE (arg
))
792 && !current_alias_ops
->ip
793 /* FIXME: Need to let analyzer decide in partial case. */
794 && (!current_alias_ops
->ip_partial
795 || !cgraph_local_info (decl
)->local
))
796 current_alias_ops
->simple_assign (current_alias_ops
, var
,
797 get_alias_var (pta_global_var
));
800 else if (TYPE_ARG_TYPES (TREE_TYPE (decl
)) != NULL
)
803 /* FIXME: Handle varargs */
804 for (arg
= TYPE_ARG_TYPES (TREE_TYPE (decl
));
805 arg
&& TREE_VALUE (arg
) != void_type_node
;
806 arg
= TREE_CHAIN (arg
))
808 tree fakedecl
= create_tmp_var_raw (TREE_VALUE (arg
), "normarg");
810 DECL_CONTEXT (fakedecl
) = current_function_decl
;
811 var
= get_alias_var (fakedecl
);
812 VARRAY_PUSH_GENERIC_PTR (params
, var
);
814 /* Incoming pointers can point to pta_global_var, unless
815 either we are interprocedural, or we can do ip on all
816 statics + this function has been defined + it's not an
817 external function. */
818 if (POINTER_TYPE_P (TREE_TYPE (fakedecl
))
819 && !current_alias_ops
->ip
820 /* FIXME: need to let analyzer decide in partial case. */
821 && (!current_alias_ops
->ip_partial
822 || !TREE_STATIC (decl
)
823 || TREE_PUBLIC (decl
)))
824 current_alias_ops
->simple_assign (current_alias_ops
, var
,
825 get_alias_var (pta_global_var
));
828 /* Functions declared like void f() are *not* equivalent to void
829 f(void). You can pass an argument to them. Thus, we need to
830 create some fake argument that would alias any actuals that get
831 passed to our function. */
834 tree fakedecl
= create_tmp_var_raw (void_type_node
, "fakearg");
836 DECL_CONTEXT (fakedecl
) = current_function_decl
;
837 fakevar
= get_alias_var (fakedecl
);
838 VARRAY_PUSH_GENERIC_PTR (params
, fakevar
);
841 if (!DECL_RESULT (decl
))
843 rdecl
= create_tmp_var_raw (TREE_TYPE (TREE_TYPE (decl
)), "_rv_");
844 retvar
= current_alias_ops
->add_var (current_alias_ops
, rdecl
);
845 DECL_PTA_ALIASVAR (rdecl
) = retvar
;
849 retvar
= current_alias_ops
->add_var (current_alias_ops
,
851 DECL_PTA_ALIASVAR (DECL_RESULT (decl
)) = retvar
;
853 VARRAY_PUSH_GENERIC_PTR (alias_vars
, retvar
);
854 ALIAS_VAR_VARNUM (retvar
) = VARRAY_ACTIVE_SIZE (alias_vars
) - 1;
855 avar
= current_alias_ops
->add_var (current_alias_ops
, decl
);
856 VARRAY_PUSH_GENERIC_PTR (alias_vars
, avar
);
857 ALIAS_VAR_VARNUM (avar
) = VARRAY_ACTIVE_SIZE (alias_vars
) - 1;
859 current_alias_ops
->function_def (current_alias_ops
, avar
, params
, retvar
);
860 DECL_PTA_ALIASVAR (decl
) = avar
;
862 /* FIXME: Also, if this is a defining declaration then add the annotation
863 to all extern definitions of the function. */
867 /* Create an alias variable for a pointer-to-member function DECL of
868 type TYPE, it's arguments, and it's return value.
869 Returns the alias_var for the PTF.
871 This includes creating alias_var's for
872 - The function itself.
874 - The return value. */
877 create_fun_alias_var_ptf (tree decl
, tree type
)
879 alias_var avar
, retvar
;
881 varray_type params
= NULL
;
883 if (DECL_PTA_ALIASVAR (decl
))
884 return DECL_PTA_ALIASVAR (decl
);
886 VARRAY_GENERIC_PTR_INIT (params
, 1, "Arguments");
888 if (TYPE_ARG_TYPES (type
) != NULL
)
891 /* FIXME: Handle varargs */
892 for (arg
= TYPE_ARG_TYPES (type
);
893 arg
&& TREE_VALUE (arg
) != void_type_node
;
894 arg
= TREE_CHAIN (arg
))
896 tree fakedecl
= create_tmp_var_raw (TREE_VALUE (arg
), "ptfarg");
898 DECL_CONTEXT (fakedecl
) = DECL_CONTEXT (decl
);
899 var
= get_alias_var (fakedecl
);
900 VARRAY_PUSH_GENERIC_PTR (params
, var
);
903 /* Functions declared like void f() are *not* equivalent to void
904 f(void). You can pass an argument to them. Thus, we need to
905 create some fake argument that would alias any actuals that get
906 passed to our function. */
909 tree fakedecl
= create_tmp_var_raw (void_type_node
, "fakearg");
911 DECL_CONTEXT (fakedecl
) = DECL_CONTEXT (decl
);
912 fakevar
= get_alias_var (fakedecl
);
913 VARRAY_PUSH_GENERIC_PTR (params
, fakevar
);
916 rdecl
= create_tmp_var_raw (TREE_TYPE (type
), "_rv_");
917 retvar
= current_alias_ops
->add_var (current_alias_ops
, rdecl
);
918 VARRAY_PUSH_GENERIC_PTR (alias_vars
, retvar
);
919 ALIAS_VAR_VARNUM (retvar
) = VARRAY_ACTIVE_SIZE (alias_vars
) - 1;
921 avar
= current_alias_ops
->add_var (current_alias_ops
, decl
);
922 VARRAY_PUSH_GENERIC_PTR (alias_vars
, avar
);
923 ALIAS_VAR_VARNUM (avar
) = VARRAY_ACTIVE_SIZE (alias_vars
) - 1;
925 current_alias_ops
->function_def (current_alias_ops
, avar
, params
, retvar
);
926 DECL_PTA_ALIASVAR (decl
) = avar
;
931 /* Create the alias_var for a *_DECL node DECL.
932 Returns the alias_var for DECL.
934 This function also handles creation of alias_var's for PTF
938 create_alias_var (tree decl
)
947 if (DECL_PTA_ALIASVAR (decl
))
948 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 && decl_function_context (var
) == NULL
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
;
1027 struct tree_opt_pass pass_build_pta
=
1031 create_alias_vars
, /* execute */
1034 0, /* static_pass_number */
1035 TV_TREE_PTA
, /* tv_id */
1036 PROP_cfg
, /* properties_required */
1037 PROP_pta
, /* properties_provided */
1038 0, /* properties_destroyed */
1039 0, /* todo_flags_start */
1040 0 /* todo_flags_finish */
1044 /* Delete created points-to sets. */
1047 delete_alias_vars (void)
1051 if (flag_tree_points_to
!= PTA_ANDERSEN
)
1054 for (i
= 0; i
< VARRAY_ACTIVE_SIZE (local_alias_vars
); i
++)
1056 tree key
= VARRAY_TREE (local_alias_vars
, i
);
1058 DECL_PTA_ALIASVAR (key
) = NULL
;
1063 for (i
= 0; i
< VARRAY_ACTIVE_SIZE (local_alias_varnums
); i
++)
1064 VARRAY_GENERIC_PTR (alias_vars
, VARRAY_INT (local_alias_varnums
, i
)) = NULL
;
1065 if (!current_alias_ops
->ip
&& !current_alias_ops
->ip_partial
)
1067 /* VARRAY_CLEAR (alias_vars); */
1068 VARRAY_CLEAR (local_alias_vars
);
1069 VARRAY_CLEAR (local_alias_varnums
);
1071 BITMAP_XFREE (addrargs
);
1072 current_alias_ops
->cleanup (current_alias_ops
);
1075 struct tree_opt_pass pass_del_pta
=
1079 delete_alias_vars
, /* execute */
1082 0, /* static_pass_number */
1083 TV_TREE_PTA
, /* tv_id */
1084 PROP_pta
, /* properties_required */
1085 0, /* properties_provided */
1086 PROP_pta
, /* properties_destroyed */
1087 0, /* todo_flags_start */
1088 0 /* todo_flags_finish */
1092 /* Initialize points-to analysis machinery. */
1095 init_alias_vars (void)
1097 current_alias_ops
->init (current_alias_ops
);
1098 addrargs
= BITMAP_XMALLOC ();
1099 VARRAY_TREE_INIT (local_alias_vars
, 10, "Local alias vars");
1100 VARRAY_INT_INIT (local_alias_varnums
, 10, "Local alias varnums");
1101 if ((!current_alias_ops
->ip
&& !current_alias_ops
->ip_partial
)
1102 || alias_vars
== NULL
)
1103 VARRAY_GENERIC_PTR_INIT (alias_vars
, 10, "Alias vars");
1106 /* Return true if PTR can't point to anything (i.e. it has an empty
1109 empty_points_to_set (tree ptr
)
1115 if (TREE_CODE (ptr
) == COMPONENT_REF
)
1116 ptr
= TREE_OPERAND (ptr
, 1);
1121 ptrtv
= DECL_PTA_ALIASVAR (ptr
);
1128 return current_alias_ops
->empty_points_to_set (current_alias_ops
, ptrtv
);
1131 /* Return true if PTR and VAR have the same points-to set. */
1134 same_points_to_set (tree ptr
, tree var
)
1136 alias_var ptrtv
, vartv
;
1140 if (TREE_CODE (ptr
) == COMPONENT_REF
)
1141 ptr
= TREE_OPERAND (ptr
, 1);
1142 if (TREE_CODE (var
) == COMPONENT_REF
)
1143 var
= TREE_OPERAND (var
, 1);
1151 ptrtv
= DECL_PTA_ALIASVAR (ptr
);
1160 vartv
= DECL_PTA_ALIASVAR (var
);
1167 return current_alias_ops
->same_points_to_set (current_alias_ops
, vartv
, ptrtv
);
1170 /* Determine whether two variables (PTR and VAR) may-alias.
1171 Returns TRUE if PTR may-alias VAR. */
1174 ptr_may_alias_var (tree ptr
, tree var
)
1176 alias_var ptrtv
, vartv
;
1180 if (TREE_CODE (ptr
) == COMPONENT_REF
)
1181 ptr
= TREE_OPERAND (ptr
, 1);
1182 if (TREE_CODE (var
) == COMPONENT_REF
)
1183 var
= TREE_OPERAND (var
, 1);
1191 ptrtv
= DECL_PTA_ALIASVAR (ptr
);
1200 vartv
= DECL_PTA_ALIASVAR (var
);
1207 return current_alias_ops
->may_alias (current_alias_ops
, ptrtv
, vartv
);
1210 #define MASK_POINTER(P) ((unsigned)((unsigned long)(P) & 0xffff))
1213 alias_get_name (tree t
)
1218 if (TREE_CODE (t
) == FIELD_DECL
)
1220 /* First get the name of the field, then the prefix, then smash them
1222 const char *fieldname
= IDENTIFIER_POINTER (DECL_NAME (t
));
1223 const char *prefix
= alias_get_name (DECL_CONTEXT (t
));
1225 size_t neededlen
= strlen (fieldname
) + strlen (prefix
) + 2;
1226 smashed
= ggc_alloc (neededlen
);
1227 sprintf (smashed
, "%s.%s", prefix
, fieldname
);
1231 else if (TYPE_P (t
))
1233 if (TYPE_NAME (t
) && IDENTIFIER_POINTER (TYPE_NAME (t
)))
1234 name
= IDENTIFIER_POINTER (TYPE_NAME (t
));
1236 name
= "<unnamed type>";
1241 if (TREE_CODE (t
) == FUNCTION_DECL
)
1242 name
= IDENTIFIER_POINTER (DECL_NAME (t
));
1243 else if (TREE_CODE (t
) == RESULT_DECL
)
1244 name
= "<return value>";
1246 name
= get_name (t
);
1253 4 = the masked pointer
1254 2 = the <> around it
1255 1 = the terminator. */
1256 namep
= ggc_alloc (2 + 4 + 2 + 1);
1257 sprintf (namep
, "<UV%x>", MASK_POINTER (t
));
1264 #include "gt-tree-alias-common.h"