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);
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
);
459 /* rhsAV might not have one, c.f. c = 5 */
460 rhsAV
= get_alias_var (op1
);
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
473 if (TREE_CODE (op1
) == COMPONENT_REF
)
474 op1
= find_op_of_decl (op1
);
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
))
489 if (is_gimple_variable (op1
))
492 current_alias_ops
->simple_assign (current_alias_ops
, lhsAV
,
496 else if (TREE_CODE (op1
) == COMPONENT_REF
497 && DECL_P (TREE_OPERAND (op1
, 0)))
500 current_alias_ops
->simple_assign (current_alias_ops
, lhsAV
,
503 /* x = (cast) [maybe-addr-expr] y */
504 else if (is_gimple_cast (op1
))
506 tree stripped_op1
= op1
;
507 STRIP_NOPS (stripped_op1
);
510 if (TREE_CODE (stripped_op1
) == ADDR_EXPR
)
511 current_alias_ops
->addr_assign (current_alias_ops
, lhsAV
,
514 current_alias_ops
->simple_assign (current_alias_ops
, lhsAV
,
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
))
525 current_alias_ops
->ptr_assign (current_alias_ops
, lhsAV
,
528 /* x = &y = x = &foo.y */
529 else if (TREE_CODE (op1
) == ADDR_EXPR
)
532 current_alias_ops
->addr_assign (current_alias_ops
, lhsAV
,
536 else if (TREE_CODE (op1
) == CALL_EXPR
)
538 /* Heap assignment. These are __attribute__ malloc or
539 something, I'll deal with it later. */
545 /* NORETURN functions have no effect on aliasing. */
546 if (call_may_return (op1
))
550 tree callop0
, callop1
;
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;
560 arg
= TREE_CHAIN (arg
), argnum
++)
562 alias_var aav
= get_alias_var (TREE_VALUE (arg
));
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
),
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
);
590 bitmap_clear (addrargs
);
591 if (TREE_CODE (op1
) == CONSTRUCTOR
)
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
,
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 */
613 VARRAY_GENERIC_PTR_INIT (ops
, 1, "Operands");
614 for (i
= 0; i
< TREE_CODE_LENGTH (TREE_CODE (op1
)); i
++)
617 op
= TREE_OPERAND (op1
, i
);
618 aav
= get_alias_var (op
);
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
,
633 /* *x = <something> */
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
))
642 current_alias_ops
->simple_assign (current_alias_ops
, lhsAV
,
645 /* x.f = &y or x->f = &y */
646 else if (TREE_CODE (op0
) == COMPONENT_REF
647 && TREE_CODE (op1
) == ADDR_EXPR
)
650 current_alias_ops
->addr_assign (current_alias_ops
, lhsAV
,
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
))
660 current_alias_ops
->assign_ptr (current_alias_ops
, lhsAV
,
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 . */
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
,
674 current_alias_ops
->assign_ptr (current_alias_ops
, lhsAV
,
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 . */
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
,
691 current_alias_ops
->assign_ptr (current_alias_ops
, lhsAV
,
696 else if ((TREE_CODE (op0
) == INDIRECT_REF
697 || TREE_CODE (op0
) == ARRAY_REF
)
698 && is_gimple_cast (op1
))
702 /* This becomes temp = (cast) y and *x = temp. */
705 temp
= create_tmp_var_raw (void_type_node
, "aliastmp");
706 tempvar
= current_alias_ops
->add_var (current_alias_ops
,
708 current_alias_ops
->simple_assign (current_alias_ops
,
710 current_alias_ops
->assign_ptr (current_alias_ops
, lhsAV
,
714 /* *x = <something else> */
718 current_alias_ops
->assign_ptr (current_alias_ops
, lhsAV
,
723 /* Calls without return values. */
724 else if (TREE_CODE (stp
) == CALL_EXPR
)
729 callvar
= get_alias_var (TREE_OPERAND (stp
, 0));
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
))
741 VARRAY_GENERIC_PTR_INIT (args
, 1, "Arguments");
742 bitmap_clear (addrargs
);
743 for (arg
= TREE_OPERAND (stp
, 1), argnum
=0;
745 arg
= TREE_CHAIN (arg
), argnum
++)
747 alias_var aav
= get_alias_var (TREE_VALUE (arg
));
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.
773 - The return value. */
776 create_fun_alias_var (tree decl
, int force
)
778 alias_var avar
, retvar
;
780 varray_type params
= NULL
;
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
)
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
)
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");
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. */
843 tree fakedecl
= create_tmp_var_raw (void_type_node
, "fakearg");
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
;
858 retvar
= current_alias_ops
->add_var (current_alias_ops
,
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. */
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.
883 - The return value. */
886 create_fun_alias_var_ptf (tree decl
, tree type
)
888 alias_var avar
, retvar
;
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
)
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");
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. */
918 tree fakedecl
= create_tmp_var_raw (void_type_node
, "fakearg");
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
;
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
947 create_alias_var (tree 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
)));
966 avar
= current_alias_ops
->add_var (current_alias_ops
, 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;
978 /* Create points-to sets for the current function. */
981 create_alias_vars (void)
985 if (flag_tree_points_to
== PTA_ANDERSEN
)
986 current_alias_ops
= andersen_alias_ops
;
990 current_alias_ops
= NULL
;
991 flag_tree_points_to
= PTA_NONE
;
995 pta_global_var
= build_decl (VAR_DECL
, get_identifier (".pta_global_var"),
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;
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
)
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. */
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
=
1040 create_alias_vars
, /* execute */
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. */
1056 delete_alias_vars (void)
1060 if (flag_tree_points_to
!= PTA_ANDERSEN
)
1063 for (i
= 0; i
< VARRAY_ACTIVE_SIZE (local_alias_vars
); i
++)
1065 tree key
= VARRAY_TREE (local_alias_vars
, i
);
1067 DECL_PTA_ALIASVAR (key
) = NULL
;
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
=
1088 delete_alias_vars
, /* execute */
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. */
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
1118 empty_points_to_set (tree ptr
)
1124 if (TREE_CODE (ptr
) == COMPONENT_REF
)
1125 ptr
= TREE_OPERAND (ptr
, 1);
1130 ptrtv
= DECL_PTA_ALIASVAR (ptr
);
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. */
1143 same_points_to_set (tree ptr
, tree var
)
1145 alias_var ptrtv
, vartv
;
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);
1160 ptrtv
= DECL_PTA_ALIASVAR (ptr
);
1169 vartv
= DECL_PTA_ALIASVAR (var
);
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. */
1183 ptr_may_alias_var (tree ptr
, tree var
)
1185 alias_var ptrtv
, vartv
;
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);
1200 ptrtv
= DECL_PTA_ALIASVAR (ptr
);
1209 vartv
= DECL_PTA_ALIASVAR (var
);
1216 return current_alias_ops
->may_alias (current_alias_ops
, ptrtv
, vartv
);
1219 #define MASK_POINTER(P) ((unsigned)((unsigned long)(P) & 0xffff))
1222 alias_get_name (tree t
)
1227 if (TREE_CODE (t
) == FIELD_DECL
)
1229 /* First get the name of the field, then the prefix, then smash them
1231 const char *fieldname
= IDENTIFIER_POINTER (DECL_NAME (t
));
1232 const char *prefix
= alias_get_name (DECL_CONTEXT (t
));
1234 size_t neededlen
= strlen (fieldname
) + strlen (prefix
) + 2;
1235 smashed
= ggc_alloc (neededlen
);
1236 sprintf (smashed
, "%s.%s", prefix
, fieldname
);
1240 else if (TYPE_P (t
))
1242 if (TYPE_NAME (t
) && IDENTIFIER_POINTER (TYPE_NAME (t
)))
1243 name
= IDENTIFIER_POINTER (TYPE_NAME (t
));
1245 name
= "<unnamed type>";
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>";
1255 name
= get_name (t
);
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
));
1273 #include "gt-tree-alias-common.h"