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 if (TREE_CODE (decl
) == FIELD_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);
154 newvar
= create_alias_var (decl
);
155 /* Assign globals to global var for purposes of intraprocedural
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
),
166 /* If the global has some DECL_INITIAL, we need to process
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
);
186 /* Get the alias_var for an expression EXPR.
187 Note that this function expects to only be handed a RHS or LHS, not
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. */
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')
207 switch (TREE_CODE (expr
))
210 case ARRAY_RANGE_REF
:
212 /* Find the first non-array ref, and return its alias variable. */
216 TREE_CODE (p
) == ARRAY_REF
|| TREE_CODE (p
) == ARRAY_RANGE_REF
;
217 p
= TREE_OPERAND (p
, 0))
219 return get_alias_var (p
);
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
)
240 for (p
= expr
; TREE_CODE (p
) == COMPONENT_REF
;
241 p
= TREE_OPERAND (p
, 0));
242 return get_alias_var (p
);
246 return get_alias_var (TREE_OPERAND (expr
, 1));
249 /* Find the first non-component ref, and return its alias variable. */
251 for (p
= expr
; TREE_CODE (p
) == COMPONENT_REF
;
252 p
= TREE_OPERAND (p
, 0));
253 return get_alias_var (p
);
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));
278 /* Perform conservative aliasing for an intraprocedural mode function
279 call. ARGS are the arguments that were passed to that function
283 intra_function_call (varray_type args
)
285 size_t l
= VARRAY_ACTIVE_SIZE (args
);
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
);
294 for (j
= 0; j
< l
; j
++)
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. */
329 get_values_from_constructor (tree constructor
, varray_type
*vals
,
330 bitmap addrargs
, int *i
)
333 switch (TREE_CODE (constructor
))
337 for (elt_list
= CONSTRUCTOR_ELTS (constructor
);
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
); }
349 aav
= get_alias_var (value
);
351 VARRAY_PUSH_GENERIC_PTR (*vals
, aav
);
352 if (TREE_CODE (value
) == ADDR_EXPR
)
353 bitmap_set_bit (addrargs
, *i
);
360 for (elt_list
= constructor
;
362 elt_list
= TREE_CHAIN (elt_list
))
364 get_values_from_constructor (TREE_VALUE (elt_list
), vals
, addrargs
, i
);
372 /* Deal with the possible return values of a call that we don't have
373 actual PTA info about. */
376 deal_with_call_aliasing (tree callargs
, alias_var lhsAV
)
380 for (argp
= callargs
;
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
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
);
396 current_alias_ops
->simple_assign (current_alias_ops
, lhsAV
,
402 /* Find the operand of the component ref that actually is doing
403 something to the DECL */
405 find_op_of_decl (tree cref
)
407 while (!DECL_P (TREE_OPERAND (cref
, 0)))
409 cref
= TREE_OPERAND (cref
, 0);
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
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. */
426 find_func_aliases (tree stp
)
428 if (TREE_CODE (stp
) == RETURN_EXPR
)
430 stp
= TREE_OPERAND (stp
, 0);
435 if (TREE_CODE (stp
) == MODIFY_EXPR
436 || (DECL_P (stp
) && DECL_INITIAL (stp
) != NULL_TREE
))
439 alias_var lhsAV
= NULL
;
440 alias_var rhsAV
= NULL
;
445 op1
= DECL_INITIAL (stp
);
449 op0
= TREE_OPERAND (stp
, 0);
450 op1
= TREE_OPERAND (stp
, 1);
452 /* lhsAV should always have an alias variable */
453 lhsAV
= get_alias_var (op0
);
456 /* rhsAV might not have one, c.f. c = 5 */
457 rhsAV
= get_alias_var (op1
);
459 while (TREE_CODE (op1
) == COMPONENT_REF
460 && TREE_CODE (TREE_OPERAND (op1
, 0)) == COMPONENT_REF
)
462 op1
= TREE_OPERAND (op1
, 0);
464 while (TREE_CODE (op1
) == BIT_FIELD_REF
)
466 op1
= TREE_OPERAND (op1
, 0);
468 /* Take care of fact that we may have multi-level component
470 if (TREE_CODE (op1
) == COMPONENT_REF
)
471 op1
= find_op_of_decl (op1
);
474 /* You would think we could test rhsAV at the top, rather than
475 50 separate times, but we can't, because it can be NULL for
476 operator assignments, where we'd still collect the individual
477 alias vars for the operator. */
479 /* Note that structures are treated as a single alias
480 variable, since we can disambiguate based on TBAA first,
481 and fall back on points-to. */
482 /* x = <something> */
483 if (is_gimple_variable (op0
))
486 if (is_gimple_variable (op1
))
489 current_alias_ops
->simple_assign (current_alias_ops
, lhsAV
,
493 else if (TREE_CODE (op1
) == COMPONENT_REF
494 && DECL_P (TREE_OPERAND (op1
, 0)))
497 current_alias_ops
->simple_assign (current_alias_ops
, lhsAV
,
500 /* x = (cast) [maybe-addr-expr] y */
501 else if (is_gimple_cast (op1
))
503 tree stripped_op1
= op1
;
504 STRIP_NOPS (stripped_op1
);
507 if (TREE_CODE (stripped_op1
) == ADDR_EXPR
)
508 current_alias_ops
->addr_assign (current_alias_ops
, lhsAV
,
511 current_alias_ops
->simple_assign (current_alias_ops
, lhsAV
,
515 /* x = *y or x = foo->y */
516 else if (TREE_CODE (op1
) == INDIRECT_REF
517 || TREE_CODE (op1
) == ARRAY_REF
518 || (TREE_CODE (op1
) == COMPONENT_REF
519 && TREE_CODE (TREE_OPERAND (op1
, 0)) == INDIRECT_REF
))
522 current_alias_ops
->ptr_assign (current_alias_ops
, lhsAV
,
525 /* x = &y = x = &foo.y */
526 else if (TREE_CODE (op1
) == ADDR_EXPR
)
529 current_alias_ops
->addr_assign (current_alias_ops
, lhsAV
,
533 else if (TREE_CODE (op1
) == CALL_EXPR
)
535 /* Heap assignment. These are __attribute__ malloc or
536 something, I'll deal with it later. */
542 /* NORETURN functions have no effect on aliasing. */
543 if (call_may_return (op1
))
547 tree callop0
, callop1
;
550 /* Collect the arguments */
551 VARRAY_GENERIC_PTR_INIT (args
, 1, "Arguments");
552 bitmap_clear (addrargs
);
553 callop1
= TREE_OPERAND (op1
, 1);
554 callop0
= TREE_OPERAND (op1
, 0);
555 for (arg
= callop1
, argnum
= 0;
557 arg
= TREE_CHAIN (arg
), argnum
++)
559 alias_var aav
= get_alias_var (TREE_VALUE (arg
));
562 VARRAY_PUSH_GENERIC_PTR (args
, aav
);
563 if (TREE_CODE (TREE_VALUE (arg
)) == ADDR_EXPR
)
564 bitmap_set_bit (addrargs
, argnum
);
567 /* Simulate the call */
568 if (current_alias_ops
->function_call (current_alias_ops
, lhsAV
,
569 get_alias_var (callop0
),
572 if (call_may_clobber (op1
)
573 && !current_alias_ops
->ip
574 && flag_argument_noalias
!= 2)
576 intra_function_call (args
);
578 if (POINTER_TYPE_P (TREE_TYPE (op0
)))
579 deal_with_call_aliasing (callop1
, lhsAV
);
587 bitmap_clear (addrargs
);
588 if (TREE_CODE (op1
) == CONSTRUCTOR
)
592 VARRAY_GENERIC_PTR_INIT (ops
, 1, "Operands");
593 get_values_from_constructor (op1
, &ops
, addrargs
, &i
);
594 current_alias_ops
->op_assign (current_alias_ops
, lhsAV
,
598 switch (TREE_CODE_CLASS (TREE_CODE (op1
)))
600 case 'e': /* an expression */
601 case 's': /* an expression with side effects */
602 case '<': /* a comparison expression */
603 case '1': /* a unary arithmetic expression */
604 case 'r': /* a reference */
605 case '2': /* a binary arithmetic expression */
610 VARRAY_GENERIC_PTR_INIT (ops
, 1, "Operands");
611 for (i
= 0; i
< TREE_CODE_LENGTH (TREE_CODE (op1
)); i
++)
614 op
= TREE_OPERAND (op1
, i
);
615 aav
= get_alias_var (op
);
617 VARRAY_PUSH_GENERIC_PTR (ops
, aav
);
618 if (TREE_CODE (op
) == ADDR_EXPR
)
619 bitmap_set_bit (addrargs
, i
);
621 current_alias_ops
->op_assign (current_alias_ops
, lhsAV
,
630 /* *x = <something> */
633 /* x.f = y or x->f = y */
634 if ((TREE_CODE (op0
) == COMPONENT_REF
635 || TREE_CODE (op0
) == BIT_FIELD_REF
)
636 && is_gimple_variable (op1
))
639 current_alias_ops
->simple_assign (current_alias_ops
, lhsAV
,
642 /* x.f = &y or x->f = &y */
643 else if (TREE_CODE (op0
) == COMPONENT_REF
644 && TREE_CODE (op1
) == ADDR_EXPR
)
647 current_alias_ops
->addr_assign (current_alias_ops
, lhsAV
,
650 /* *x.f = y or *x->f = y */
651 else if ((TREE_CODE (op0
) == INDIRECT_REF
652 || TREE_CODE (op0
) == ARRAY_REF
)
653 && TREE_CODE (TREE_OPERAND (op0
, 0)) == COMPONENT_REF
654 && is_gimple_variable (op1
))
657 current_alias_ops
->assign_ptr (current_alias_ops
, lhsAV
,
661 else if ((TREE_CODE (op0
) == INDIRECT_REF
662 || TREE_CODE (op0
) == ARRAY_REF
)
663 && TREE_CODE (op1
) == ADDR_EXPR
)
665 /* This becomes temp = &y and *x = temp . */
667 tree temp
= create_tmp_var_raw (void_type_node
, "aliastmp");
668 tempvar
= current_alias_ops
->add_var (current_alias_ops
, temp
);
669 current_alias_ops
->addr_assign (current_alias_ops
, tempvar
,
671 current_alias_ops
->assign_ptr (current_alias_ops
, lhsAV
,
676 else if ((TREE_CODE (op0
) == INDIRECT_REF
677 || TREE_CODE (op0
) == ARRAY_REF
)
678 && (TREE_CODE (op1
) == INDIRECT_REF
679 || TREE_CODE (op1
) == ARRAY_REF
))
681 /* This becomes temp = *y and *x = temp . */
684 temp
= create_tmp_var_raw (void_type_node
, "aliastmp");
685 tempvar
= current_alias_ops
->add_var (current_alias_ops
, temp
);
686 current_alias_ops
->ptr_assign (current_alias_ops
, tempvar
,
688 current_alias_ops
->assign_ptr (current_alias_ops
, lhsAV
,
693 else if ((TREE_CODE (op0
) == INDIRECT_REF
694 || TREE_CODE (op0
) == ARRAY_REF
)
695 && is_gimple_cast (op1
))
699 /* This becomes temp = (cast) y and *x = temp. */
702 temp
= create_tmp_var_raw (void_type_node
, "aliastmp");
703 tempvar
= current_alias_ops
->add_var (current_alias_ops
,
705 current_alias_ops
->simple_assign (current_alias_ops
,
707 current_alias_ops
->assign_ptr (current_alias_ops
, lhsAV
,
711 /* *x = <something else> */
715 current_alias_ops
->assign_ptr (current_alias_ops
, lhsAV
,
720 /* Calls without return values. */
721 else if (TREE_CODE (stp
) == CALL_EXPR
)
726 callvar
= get_alias_var (TREE_OPERAND (stp
, 0));
730 /* NORETURN and CONST functions with no return value
731 have no effect on aliasing (as may be seen above,
732 const functions that return a value might have an
733 effect on aliasing, since the return value can point
734 to one of the arguments. */
735 if (call_may_clobber (stp
))
738 VARRAY_GENERIC_PTR_INIT (args
, 1, "Arguments");
739 bitmap_clear (addrargs
);
740 for (arg
= TREE_OPERAND (stp
, 1), argnum
=0;
742 arg
= TREE_CHAIN (arg
), argnum
++)
744 alias_var aav
= get_alias_var (TREE_VALUE (arg
));
747 VARRAY_PUSH_GENERIC_PTR (args
, aav
);
748 if (TREE_CODE (TREE_VALUE (arg
)) == ADDR_EXPR
)
749 bitmap_set_bit (addrargs
, argnum
);
754 if (current_alias_ops
->function_call (current_alias_ops
, NULL
,
755 callvar
, args
, addrargs
))
756 if (!current_alias_ops
->ip
&& flag_argument_noalias
!= 2)
757 intra_function_call (args
);
763 /* Create the alias_var for a function definition DECL, it's
764 arguments, and it's return value. If FORCE is true, we force
765 creation of the alias_var, regardless of whether one exists already.
767 This includes creation of alias_var's for
768 - The function itself.
770 - The return value. */
773 create_fun_alias_var (tree decl
, int force
)
775 alias_var avar
, retvar
;
777 varray_type params
= NULL
;
781 if (DECL_PTA_ALIASVAR (decl
))
782 return DECL_PTA_ALIASVAR (decl
);
785 VARRAY_GENERIC_PTR_INIT (params
, 1, "Arguments");
786 if (DECL_ARGUMENTS (decl
) != NULL
)
789 for (arg
= DECL_ARGUMENTS (decl
); arg
; arg
= TREE_CHAIN (arg
))
791 alias_var var
= get_alias_var (arg
);
792 VARRAY_PUSH_GENERIC_PTR (params
, var
);
793 /* Incoming pointers can point to pta_global_var, unless
794 either we are interprocedural, or we can do ip on all
795 statics + this function has been defined + it's not an
796 external function. */
797 if (POINTER_TYPE_P (TREE_TYPE (arg
))
798 && !current_alias_ops
->ip
799 /* FIXME: Need to let analyzer decide in partial case. */
800 && (!current_alias_ops
->ip_partial
801 || !cgraph_local_info (decl
)->local
))
802 current_alias_ops
->simple_assign (current_alias_ops
, var
,
803 get_alias_var (pta_global_var
));
806 else if (TYPE_ARG_TYPES (TREE_TYPE (decl
)) != NULL
)
809 /* FIXME: Handle varargs */
810 for (arg
= TYPE_ARG_TYPES (TREE_TYPE (decl
));
811 arg
&& TREE_VALUE (arg
) != void_type_node
;
812 arg
= TREE_CHAIN (arg
))
814 tree fakedecl
= create_tmp_var_raw (TREE_VALUE (arg
), "normarg");
816 DECL_CONTEXT (fakedecl
) = current_function_decl
;
817 var
= get_alias_var (fakedecl
);
818 VARRAY_PUSH_GENERIC_PTR (params
, var
);
820 /* Incoming pointers can point to pta_global_var, unless
821 either we are interprocedural, or we can do ip on all
822 statics + this function has been defined + it's not an
823 external function. */
824 if (POINTER_TYPE_P (TREE_TYPE (fakedecl
))
825 && !current_alias_ops
->ip
826 /* FIXME: need to let analyzer decide in partial case. */
827 && (!current_alias_ops
->ip_partial
828 || !TREE_STATIC (decl
)
829 || TREE_PUBLIC (decl
)))
830 current_alias_ops
->simple_assign (current_alias_ops
, var
,
831 get_alias_var (pta_global_var
));
834 /* Functions declared like void f() are *not* equivalent to void
835 f(void). You can pass an argument to them. Thus, we need to
836 create some fake argument that would alias any actuals that get
837 passed to our function. */
840 tree fakedecl
= create_tmp_var_raw (void_type_node
, "fakearg");
842 DECL_CONTEXT (fakedecl
) = current_function_decl
;
843 fakevar
= get_alias_var (fakedecl
);
844 VARRAY_PUSH_GENERIC_PTR (params
, fakevar
);
847 if (!DECL_RESULT (decl
))
849 rdecl
= create_tmp_var_raw (TREE_TYPE (TREE_TYPE (decl
)), "_rv_");
850 retvar
= current_alias_ops
->add_var (current_alias_ops
, rdecl
);
851 DECL_PTA_ALIASVAR (rdecl
) = retvar
;
855 retvar
= current_alias_ops
->add_var (current_alias_ops
,
857 DECL_PTA_ALIASVAR (DECL_RESULT (decl
)) = retvar
;
859 VARRAY_PUSH_GENERIC_PTR (alias_vars
, retvar
);
860 ALIAS_VAR_VARNUM (retvar
) = VARRAY_ACTIVE_SIZE (alias_vars
) - 1;
861 avar
= current_alias_ops
->add_var (current_alias_ops
, decl
);
862 VARRAY_PUSH_GENERIC_PTR (alias_vars
, avar
);
863 ALIAS_VAR_VARNUM (avar
) = VARRAY_ACTIVE_SIZE (alias_vars
) - 1;
865 current_alias_ops
->function_def (current_alias_ops
, avar
, params
, retvar
);
866 DECL_PTA_ALIASVAR (decl
) = avar
;
868 /* FIXME: Also, if this is a defining declaration then add the annotation
869 to all extern definitions of the function. */
873 /* Create an alias variable for a pointer-to-member function DECL of
874 type TYPE, it's arguments, and it's return value.
875 Returns the alias_var for the PTF.
877 This includes creating alias_var's for
878 - The function itself.
880 - The return value. */
883 create_fun_alias_var_ptf (tree decl
, tree type
)
885 alias_var avar
, retvar
;
887 varray_type params
= NULL
;
889 if (DECL_PTA_ALIASVAR (decl
))
890 return DECL_PTA_ALIASVAR (decl
);
892 VARRAY_GENERIC_PTR_INIT (params
, 1, "Arguments");
894 if (TYPE_ARG_TYPES (type
) != NULL
)
897 /* FIXME: Handle varargs */
898 for (arg
= TYPE_ARG_TYPES (type
);
899 arg
&& TREE_VALUE (arg
) != void_type_node
;
900 arg
= TREE_CHAIN (arg
))
902 tree fakedecl
= create_tmp_var_raw (TREE_VALUE (arg
), "ptfarg");
904 DECL_CONTEXT (fakedecl
) = DECL_CONTEXT (decl
);
905 var
= get_alias_var (fakedecl
);
906 VARRAY_PUSH_GENERIC_PTR (params
, var
);
909 /* Functions declared like void f() are *not* equivalent to void
910 f(void). You can pass an argument to them. Thus, we need to
911 create some fake argument that would alias any actuals that get
912 passed to our function. */
915 tree fakedecl
= create_tmp_var_raw (void_type_node
, "fakearg");
917 DECL_CONTEXT (fakedecl
) = DECL_CONTEXT (decl
);
918 fakevar
= get_alias_var (fakedecl
);
919 VARRAY_PUSH_GENERIC_PTR (params
, fakevar
);
922 rdecl
= create_tmp_var_raw (TREE_TYPE (type
), "_rv_");
923 retvar
= current_alias_ops
->add_var (current_alias_ops
, rdecl
);
924 VARRAY_PUSH_GENERIC_PTR (alias_vars
, retvar
);
925 ALIAS_VAR_VARNUM (retvar
) = VARRAY_ACTIVE_SIZE (alias_vars
) - 1;
927 avar
= current_alias_ops
->add_var (current_alias_ops
, decl
);
928 VARRAY_PUSH_GENERIC_PTR (alias_vars
, avar
);
929 ALIAS_VAR_VARNUM (avar
) = VARRAY_ACTIVE_SIZE (alias_vars
) - 1;
931 current_alias_ops
->function_def (current_alias_ops
, avar
, params
, retvar
);
932 DECL_PTA_ALIASVAR (decl
) = avar
;
937 /* Create the alias_var for a *_DECL node DECL.
938 Returns the alias_var for DECL.
940 This function also handles creation of alias_var's for PTF
944 create_alias_var (tree decl
)
953 if (DECL_PTA_ALIASVAR (decl
))
954 return DECL_PTA_ALIASVAR (decl
);
957 if (POINTER_TYPE_P (TREE_TYPE (decl
))
958 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl
))) == FUNCTION_TYPE
)
960 avar
= create_fun_alias_var_ptf (decl
, TREE_TYPE (TREE_TYPE (decl
)));
963 avar
= current_alias_ops
->add_var (current_alias_ops
, decl
);
967 DECL_PTA_ALIASVAR (decl
) = avar
;
970 VARRAY_PUSH_GENERIC_PTR (alias_vars
, avar
);
971 ALIAS_VAR_VARNUM (avar
) = VARRAY_ACTIVE_SIZE (alias_vars
) - 1;
975 /* Create points-to sets for the current function. */
978 create_alias_vars (void)
982 if (flag_tree_points_to
== PTA_ANDERSEN
)
983 current_alias_ops
= andersen_alias_ops
;
987 current_alias_ops
= NULL
;
988 flag_tree_points_to
= PTA_NONE
;
992 pta_global_var
= build_decl (VAR_DECL
, get_identifier (".pta_global_var"),
994 DECL_ARTIFICIAL (pta_global_var
) = 1;
995 TREE_READONLY (pta_global_var
) = 1;
996 DECL_EXTERNAL (pta_global_var
) = 0;
997 TREE_STATIC (pta_global_var
) = 1;
998 TREE_USED (pta_global_var
) = 1;
999 DECL_CONTEXT (pta_global_var
) = current_function_decl
;
1000 TREE_THIS_VOLATILE (pta_global_var
) = 1;
1001 TREE_ADDRESSABLE (pta_global_var
) = 0;
1005 DECL_PTA_ALIASVAR (current_function_decl
) = NULL
;
1006 get_alias_var (current_function_decl
);
1008 /* First, walk the variables and their DECL_INITIAL's */
1009 if (cfun
->unexpanded_var_list
)
1012 for (vars
= cfun
->unexpanded_var_list
; vars
; vars
= TREE_CHAIN (vars
))
1014 var
= TREE_VALUE (vars
);
1015 if (TREE_CODE (var
) != LABEL_DECL
1016 && decl_function_context (var
) == NULL
1017 && DECL_INITIAL (var
))
1018 find_func_aliases (var
);
1022 /* Now walk all statements and derive aliases. */
1025 block_stmt_iterator bsi
;
1026 for (bsi
= bsi_start (bb
); !bsi_end_p (bsi
); bsi_next (&bsi
))
1027 find_func_aliases (bsi_stmt (bsi
));
1030 pta_global_var
= NULL_TREE
;
1033 struct tree_opt_pass pass_build_pta
=
1037 create_alias_vars
, /* execute */
1040 0, /* static_pass_number */
1041 TV_TREE_PTA
, /* tv_id */
1042 PROP_cfg
, /* properties_required */
1043 PROP_pta
, /* properties_provided */
1044 0, /* properties_destroyed */
1045 0, /* todo_flags_start */
1046 0 /* todo_flags_finish */
1050 /* Delete created points-to sets. */
1053 delete_alias_vars (void)
1057 if (flag_tree_points_to
!= PTA_ANDERSEN
)
1060 for (i
= 0; i
< VARRAY_ACTIVE_SIZE (local_alias_vars
); i
++)
1062 tree key
= VARRAY_TREE (local_alias_vars
, i
);
1064 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
=
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 */
1098 /* Initialize points-to analysis machinery. */
1101 init_alias_vars (void)
1103 current_alias_ops
->init (current_alias_ops
);
1104 addrargs
= BITMAP_XMALLOC ();
1105 VARRAY_TREE_INIT (local_alias_vars
, 10, "Local alias vars");
1106 VARRAY_INT_INIT (local_alias_varnums
, 10, "Local alias varnums");
1107 if ((!current_alias_ops
->ip
&& !current_alias_ops
->ip_partial
)
1108 || alias_vars
== NULL
)
1109 VARRAY_GENERIC_PTR_INIT (alias_vars
, 10, "Alias vars");
1112 /* Return true if PTR can't point to anything (i.e. it has an empty
1115 empty_points_to_set (tree ptr
)
1121 if (TREE_CODE (ptr
) == COMPONENT_REF
)
1122 ptr
= TREE_OPERAND (ptr
, 1);
1127 ptrtv
= DECL_PTA_ALIASVAR (ptr
);
1134 return current_alias_ops
->empty_points_to_set (current_alias_ops
, ptrtv
);
1137 /* Return true if PTR and VAR have the same points-to set. */
1140 same_points_to_set (tree ptr
, tree var
)
1142 alias_var ptrtv
, vartv
;
1146 if (TREE_CODE (ptr
) == COMPONENT_REF
)
1147 ptr
= TREE_OPERAND (ptr
, 1);
1148 if (TREE_CODE (var
) == COMPONENT_REF
)
1149 var
= TREE_OPERAND (var
, 1);
1157 ptrtv
= DECL_PTA_ALIASVAR (ptr
);
1166 vartv
= DECL_PTA_ALIASVAR (var
);
1173 return current_alias_ops
->same_points_to_set (current_alias_ops
, vartv
, ptrtv
);
1176 /* Determine whether two variables (PTR and VAR) may-alias.
1177 Returns TRUE if PTR may-alias VAR. */
1180 ptr_may_alias_var (tree ptr
, tree var
)
1182 alias_var ptrtv
, vartv
;
1186 if (TREE_CODE (ptr
) == COMPONENT_REF
)
1187 ptr
= TREE_OPERAND (ptr
, 1);
1188 if (TREE_CODE (var
) == COMPONENT_REF
)
1189 var
= TREE_OPERAND (var
, 1);
1197 ptrtv
= DECL_PTA_ALIASVAR (ptr
);
1206 vartv
= DECL_PTA_ALIASVAR (var
);
1213 return current_alias_ops
->may_alias (current_alias_ops
, ptrtv
, vartv
);
1216 #define MASK_POINTER(P) ((unsigned)((unsigned long)(P) & 0xffff))
1219 alias_get_name (tree t
)
1224 if (TREE_CODE (t
) == FIELD_DECL
)
1226 /* First get the name of the field, then the prefix, then smash them
1228 const char *fieldname
= IDENTIFIER_POINTER (DECL_NAME (t
));
1229 const char *prefix
= alias_get_name (DECL_CONTEXT (t
));
1231 size_t neededlen
= strlen (fieldname
) + strlen (prefix
) + 2;
1232 smashed
= ggc_alloc (neededlen
);
1233 sprintf (smashed
, "%s.%s", prefix
, fieldname
);
1237 else if (TYPE_P (t
))
1239 if (TYPE_NAME (t
) && IDENTIFIER_POINTER (TYPE_NAME (t
)))
1240 name
= IDENTIFIER_POINTER (TYPE_NAME (t
));
1242 name
= "<unnamed type>";
1247 if (TREE_CODE (t
) == FUNCTION_DECL
)
1248 name
= IDENTIFIER_POINTER (DECL_NAME (t
));
1249 else if (TREE_CODE (t
) == RESULT_DECL
)
1250 name
= "<return value>";
1252 name
= get_name (t
);
1259 4 = the masked pointer
1260 2 = the <> around it
1261 1 = the terminator. */
1262 namep
= ggc_alloc (2 + 4 + 2 + 1);
1263 sprintf (namep
, "<UV%x>", MASK_POINTER (t
));
1270 #include "gt-tree-alias-common.h"