Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-ssa-structalias.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
1 /* Tree based points-to analysis | 1 /* Tree based points-to analysis |
2 Copyright (C) 2005-2017 Free Software Foundation, Inc. | 2 Copyright (C) 2005-2018 Free Software Foundation, Inc. |
3 Contributed by Daniel Berlin <dberlin@dberlin.org> | 3 Contributed by Daniel Berlin <dberlin@dberlin.org> |
4 | 4 |
5 This file is part of GCC. | 5 This file is part of GCC. |
6 | 6 |
7 GCC is free software; you can redistribute it and/or modify | 7 GCC is free software; you can redistribute it and/or modify |
40 #include "params.h" | 40 #include "params.h" |
41 #include "gimple-walk.h" | 41 #include "gimple-walk.h" |
42 #include "varasm.h" | 42 #include "varasm.h" |
43 #include "stringpool.h" | 43 #include "stringpool.h" |
44 #include "attribs.h" | 44 #include "attribs.h" |
45 #include "tree-ssa.h" | |
45 | 46 |
46 /* The idea behind this analyzer is to generate set constraints from the | 47 /* The idea behind this analyzer is to generate set constraints from the |
47 program, then solve the resulting constraints in order to generate the | 48 program, then solve the resulting constraints in order to generate the |
48 points-to sets. | 49 points-to sets. |
49 | 50 |
2926 varinfo_t vi; | 2927 varinfo_t vi; |
2927 | 2928 |
2928 /* We allow FUNCTION_DECLs here even though it doesn't make much sense. */ | 2929 /* We allow FUNCTION_DECLs here even though it doesn't make much sense. */ |
2929 gcc_assert (TREE_CODE (t) == SSA_NAME || DECL_P (t)); | 2930 gcc_assert (TREE_CODE (t) == SSA_NAME || DECL_P (t)); |
2930 | 2931 |
2931 /* For parameters, get at the points-to set for the actual parm | |
2932 decl. */ | |
2933 if (TREE_CODE (t) == SSA_NAME | 2932 if (TREE_CODE (t) == SSA_NAME |
2934 && SSA_NAME_IS_DEFAULT_DEF (t) | 2933 && SSA_NAME_IS_DEFAULT_DEF (t)) |
2935 && (TREE_CODE (SSA_NAME_VAR (t)) == PARM_DECL | 2934 { |
2936 || TREE_CODE (SSA_NAME_VAR (t)) == RESULT_DECL)) | 2935 /* For parameters, get at the points-to set for the actual parm |
2937 { | 2936 decl. */ |
2938 get_constraint_for_ssa_var (SSA_NAME_VAR (t), results, address_p); | 2937 if (TREE_CODE (SSA_NAME_VAR (t)) == PARM_DECL |
2939 return; | 2938 || TREE_CODE (SSA_NAME_VAR (t)) == RESULT_DECL) |
2939 { | |
2940 get_constraint_for_ssa_var (SSA_NAME_VAR (t), results, address_p); | |
2941 return; | |
2942 } | |
2943 /* For undefined SSA names return nothing. */ | |
2944 else if (!ssa_defined_default_def_p (t)) | |
2945 { | |
2946 cexpr.var = nothing_id; | |
2947 cexpr.type = SCALAR; | |
2948 cexpr.offset = 0; | |
2949 results->safe_push (cexpr); | |
2950 return; | |
2951 } | |
2940 } | 2952 } |
2941 | 2953 |
2942 /* For global variables resort to the alias target. */ | 2954 /* For global variables resort to the alias target. */ |
2943 if (VAR_P (t) && (TREE_STATIC (t) || DECL_EXTERNAL (t))) | 2955 if (VAR_P (t) && (TREE_STATIC (t) || DECL_EXTERNAL (t))) |
2944 { | 2956 { |
3189 static void | 3201 static void |
3190 get_constraint_for_component_ref (tree t, vec<ce_s> *results, | 3202 get_constraint_for_component_ref (tree t, vec<ce_s> *results, |
3191 bool address_p, bool lhs_p) | 3203 bool address_p, bool lhs_p) |
3192 { | 3204 { |
3193 tree orig_t = t; | 3205 tree orig_t = t; |
3194 HOST_WIDE_INT bitsize = -1; | 3206 poly_int64 bitsize = -1; |
3195 HOST_WIDE_INT bitmaxsize = -1; | 3207 poly_int64 bitmaxsize = -1; |
3196 HOST_WIDE_INT bitpos; | 3208 poly_int64 bitpos; |
3197 bool reverse; | 3209 bool reverse; |
3198 tree forzero; | 3210 tree forzero; |
3199 | 3211 |
3200 /* Some people like to do cute things like take the address of | 3212 /* Some people like to do cute things like take the address of |
3201 &0->a.b */ | 3213 &0->a.b */ |
3253 /* In languages like C, you can access one past the end of an | 3265 /* In languages like C, you can access one past the end of an |
3254 array. You aren't allowed to dereference it, so we can | 3266 array. You aren't allowed to dereference it, so we can |
3255 ignore this constraint. When we handle pointer subtraction, | 3267 ignore this constraint. When we handle pointer subtraction, |
3256 we may have to do something cute here. */ | 3268 we may have to do something cute here. */ |
3257 | 3269 |
3258 if ((unsigned HOST_WIDE_INT)bitpos < get_varinfo (result.var)->fullsize | 3270 if (maybe_lt (poly_uint64 (bitpos), get_varinfo (result.var)->fullsize) |
3259 && bitmaxsize != 0) | 3271 && maybe_ne (bitmaxsize, 0)) |
3260 { | 3272 { |
3261 /* It's also not true that the constraint will actually start at the | 3273 /* It's also not true that the constraint will actually start at the |
3262 right offset, it may start in some padding. We only care about | 3274 right offset, it may start in some padding. We only care about |
3263 setting the constraint to the first actual field it touches, so | 3275 setting the constraint to the first actual field it touches, so |
3264 walk to find it. */ | 3276 walk to find it. */ |
3266 varinfo_t curr; | 3278 varinfo_t curr; |
3267 results->pop (); | 3279 results->pop (); |
3268 cexpr.offset = 0; | 3280 cexpr.offset = 0; |
3269 for (curr = get_varinfo (cexpr.var); curr; curr = vi_next (curr)) | 3281 for (curr = get_varinfo (cexpr.var); curr; curr = vi_next (curr)) |
3270 { | 3282 { |
3271 if (ranges_overlap_p (curr->offset, curr->size, | 3283 if (ranges_maybe_overlap_p (poly_int64 (curr->offset), |
3272 bitpos, bitmaxsize)) | 3284 curr->size, bitpos, bitmaxsize)) |
3273 { | 3285 { |
3274 cexpr.var = curr->id; | 3286 cexpr.var = curr->id; |
3275 results->safe_push (cexpr); | 3287 results->safe_push (cexpr); |
3276 if (address_p) | 3288 if (address_p) |
3277 break; | 3289 break; |
3300 cexpr.var = anything_id; | 3312 cexpr.var = anything_id; |
3301 cexpr.offset = 0; | 3313 cexpr.offset = 0; |
3302 results->safe_push (cexpr); | 3314 results->safe_push (cexpr); |
3303 } | 3315 } |
3304 } | 3316 } |
3305 else if (bitmaxsize == 0) | 3317 else if (known_eq (bitmaxsize, 0)) |
3306 { | 3318 { |
3307 if (dump_file && (dump_flags & TDF_DETAILS)) | 3319 if (dump_file && (dump_flags & TDF_DETAILS)) |
3308 fprintf (dump_file, "Access to zero-sized part of variable, " | 3320 fprintf (dump_file, "Access to zero-sized part of variable, " |
3309 "ignoring\n"); | 3321 "ignoring\n"); |
3310 } | 3322 } |
3315 else if (result.type == DEREF) | 3327 else if (result.type == DEREF) |
3316 { | 3328 { |
3317 /* If we do not know exactly where the access goes say so. Note | 3329 /* If we do not know exactly where the access goes say so. Note |
3318 that only for non-structure accesses we know that we access | 3330 that only for non-structure accesses we know that we access |
3319 at most one subfiled of any variable. */ | 3331 at most one subfiled of any variable. */ |
3320 if (bitpos == -1 | 3332 HOST_WIDE_INT const_bitpos; |
3321 || bitsize != bitmaxsize | 3333 if (!bitpos.is_constant (&const_bitpos) |
3334 || const_bitpos == -1 | |
3335 || maybe_ne (bitsize, bitmaxsize) | |
3322 || AGGREGATE_TYPE_P (TREE_TYPE (orig_t)) | 3336 || AGGREGATE_TYPE_P (TREE_TYPE (orig_t)) |
3323 || result.offset == UNKNOWN_OFFSET) | 3337 || result.offset == UNKNOWN_OFFSET) |
3324 result.offset = UNKNOWN_OFFSET; | 3338 result.offset = UNKNOWN_OFFSET; |
3325 else | 3339 else |
3326 result.offset += bitpos; | 3340 result.offset += const_bitpos; |
3327 } | 3341 } |
3328 else if (result.type == ADDRESSOF) | 3342 else if (result.type == ADDRESSOF) |
3329 { | 3343 { |
3330 /* We can end up here for component references on constants like | 3344 /* We can end up here for component references on constants like |
3331 VIEW_CONVERT_EXPR <>({ 0, 1, 2, 3 })[i]. */ | 3345 VIEW_CONVERT_EXPR <>({ 0, 1, 2, 3 })[i]. */ |
3658 } | 3672 } |
3659 else if (lhsp->type == SCALAR | 3673 else if (lhsp->type == SCALAR |
3660 && (rhsp->type == SCALAR | 3674 && (rhsp->type == SCALAR |
3661 || rhsp->type == ADDRESSOF)) | 3675 || rhsp->type == ADDRESSOF)) |
3662 { | 3676 { |
3663 HOST_WIDE_INT lhssize, lhsmaxsize, lhsoffset; | 3677 HOST_WIDE_INT lhssize, lhsoffset; |
3664 HOST_WIDE_INT rhssize, rhsmaxsize, rhsoffset; | 3678 HOST_WIDE_INT rhssize, rhsoffset; |
3665 bool reverse; | 3679 bool reverse; |
3666 unsigned k = 0; | 3680 unsigned k = 0; |
3667 get_ref_base_and_extent (lhsop, &lhsoffset, &lhssize, &lhsmaxsize, | 3681 if (!get_ref_base_and_extent_hwi (lhsop, &lhsoffset, &lhssize, &reverse) |
3668 &reverse); | 3682 || !get_ref_base_and_extent_hwi (rhsop, &rhsoffset, &rhssize, |
3669 get_ref_base_and_extent (rhsop, &rhsoffset, &rhssize, &rhsmaxsize, | 3683 &reverse)) |
3670 &reverse); | 3684 { |
3685 process_all_all_constraints (lhsc, rhsc); | |
3686 return; | |
3687 } | |
3671 for (j = 0; lhsc.iterate (j, &lhsp);) | 3688 for (j = 0; lhsc.iterate (j, &lhsp);) |
3672 { | 3689 { |
3673 varinfo_t lhsv, rhsv; | 3690 varinfo_t lhsv, rhsv; |
3674 rhsp = &rhsc[k]; | 3691 rhsp = &rhsc[k]; |
3675 lhsv = get_varinfo (lhsp->var); | 3692 lhsv = get_varinfo (lhsp->var); |
3896 /* ??? We probably should have a ANYFN special variable. */ | 3913 /* ??? We probably should have a ANYFN special variable. */ |
3897 c.var = anything_id; | 3914 c.var = anything_id; |
3898 c.offset = 0; | 3915 c.offset = 0; |
3899 c.type = SCALAR; | 3916 c.type = SCALAR; |
3900 } | 3917 } |
3901 else if (TREE_CODE (fi->decl) == FUNCTION_DECL) | 3918 else if (fi->decl && TREE_CODE (fi->decl) == FUNCTION_DECL) |
3902 { | 3919 { |
3903 varinfo_t ai = first_vi_for_offset (fi, part); | 3920 varinfo_t ai = first_vi_for_offset (fi, part); |
3904 if (ai) | 3921 if (ai) |
3905 c.var = ai->id; | 3922 c.var = ai->id; |
3906 else | 3923 else |
4068 vi->is_global_var = 0; | 4085 vi->is_global_var = 0; |
4069 /* If this is not a real malloc call assume the memory was | 4086 /* If this is not a real malloc call assume the memory was |
4070 initialized and thus may point to global memory. All | 4087 initialized and thus may point to global memory. All |
4071 builtin functions with the malloc attribute behave in a sane way. */ | 4088 builtin functions with the malloc attribute behave in a sane way. */ |
4072 if (!fndecl | 4089 if (!fndecl |
4073 || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL) | 4090 || !fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)) |
4074 make_constraint_from (vi, nonlocal_id); | 4091 make_constraint_from (vi, nonlocal_id); |
4075 tmpc.var = vi->id; | 4092 tmpc.var = vi->id; |
4076 tmpc.offset = 0; | 4093 tmpc.offset = 0; |
4077 tmpc.type = ADDRESSOF; | 4094 tmpc.type = ADDRESSOF; |
4078 rhsc.safe_push (tmpc); | 4095 rhsc.safe_push (tmpc); |
4491 return true; | 4508 return true; |
4492 /* Pure functions that return something not based on any object and | 4509 /* Pure functions that return something not based on any object and |
4493 that use the memory pointed to by their arguments (but not | 4510 that use the memory pointed to by their arguments (but not |
4494 transitively). */ | 4511 transitively). */ |
4495 case BUILT_IN_STRCMP: | 4512 case BUILT_IN_STRCMP: |
4513 case BUILT_IN_STRCMP_EQ: | |
4496 case BUILT_IN_STRNCMP: | 4514 case BUILT_IN_STRNCMP: |
4515 case BUILT_IN_STRNCMP_EQ: | |
4497 case BUILT_IN_STRCASECMP: | 4516 case BUILT_IN_STRCASECMP: |
4498 case BUILT_IN_STRNCASECMP: | 4517 case BUILT_IN_STRNCASECMP: |
4499 case BUILT_IN_MEMCMP: | 4518 case BUILT_IN_MEMCMP: |
4500 case BUILT_IN_BCMP: | 4519 case BUILT_IN_BCMP: |
4501 case BUILT_IN_STRSPN: | 4520 case BUILT_IN_STRSPN: |
4720 { | 4739 { |
4721 tree fndecl = gimple_call_fndecl (t); | 4740 tree fndecl = gimple_call_fndecl (t); |
4722 varinfo_t fi; | 4741 varinfo_t fi; |
4723 | 4742 |
4724 if (fndecl != NULL_TREE | 4743 if (fndecl != NULL_TREE |
4725 && DECL_BUILT_IN (fndecl) | 4744 && fndecl_built_in_p (fndecl) |
4726 && find_func_aliases_for_builtin_call (fn, t)) | 4745 && find_func_aliases_for_builtin_call (fn, t)) |
4727 return; | 4746 return; |
4728 | 4747 |
4729 fi = get_fi_for_callee (t); | 4748 fi = get_fi_for_callee (t); |
4730 if (!in_ipa_mode | 4749 if (!in_ipa_mode |
4731 || (fndecl && !fi->is_fn_info)) | 4750 || (fi->decl && fndecl && !fi->is_fn_info)) |
4732 { | 4751 { |
4733 auto_vec<ce_s, 16> rhsc; | 4752 auto_vec<ce_s, 16> rhsc; |
4734 int flags = gimple_call_flags (t); | 4753 int flags = gimple_call_flags (t); |
4735 | 4754 |
4736 /* Const functions can return their arguments and addresses | 4755 /* Const functions can return their arguments and addresses |
4824 find_func_aliases (struct function *fn, gimple *origt) | 4843 find_func_aliases (struct function *fn, gimple *origt) |
4825 { | 4844 { |
4826 gimple *t = origt; | 4845 gimple *t = origt; |
4827 auto_vec<ce_s, 16> lhsc; | 4846 auto_vec<ce_s, 16> lhsc; |
4828 auto_vec<ce_s, 16> rhsc; | 4847 auto_vec<ce_s, 16> rhsc; |
4829 struct constraint_expr *c; | |
4830 varinfo_t fi; | 4848 varinfo_t fi; |
4831 | 4849 |
4832 /* Now build constraints expressions. */ | 4850 /* Now build constraints expressions. */ |
4833 if (gimple_code (t) == GIMPLE_PHI) | 4851 if (gimple_code (t) == GIMPLE_PHI) |
4834 { | 4852 { |
4835 size_t i; | |
4836 unsigned int j; | |
4837 | |
4838 /* For a phi node, assign all the arguments to | 4853 /* For a phi node, assign all the arguments to |
4839 the result. */ | 4854 the result. */ |
4840 get_constraint_for (gimple_phi_result (t), &lhsc); | 4855 get_constraint_for (gimple_phi_result (t), &lhsc); |
4841 for (i = 0; i < gimple_phi_num_args (t); i++) | 4856 for (unsigned i = 0; i < gimple_phi_num_args (t); i++) |
4842 { | 4857 { |
4843 tree strippedrhs = PHI_ARG_DEF (t, i); | |
4844 | |
4845 STRIP_NOPS (strippedrhs); | |
4846 get_constraint_for_rhs (gimple_phi_arg_def (t, i), &rhsc); | 4858 get_constraint_for_rhs (gimple_phi_arg_def (t, i), &rhsc); |
4847 | 4859 process_all_all_constraints (lhsc, rhsc); |
4848 FOR_EACH_VEC_ELT (lhsc, j, c) | 4860 rhsc.truncate (0); |
4849 { | |
4850 struct constraint_expr *c2; | |
4851 while (rhsc.length () > 0) | |
4852 { | |
4853 c2 = &rhsc.last (); | |
4854 process_constraint (new_constraint (*c, *c2)); | |
4855 rhsc.pop (); | |
4856 } | |
4857 } | |
4858 } | 4861 } |
4859 } | 4862 } |
4860 /* In IPA mode, we need to generate constraints to pass call | 4863 /* In IPA mode, we need to generate constraints to pass call |
4861 arguments through their calls. There are two cases, | 4864 arguments through their calls. There are two cases, |
4862 either a GIMPLE_CALL returning a value, or just a plain | 4865 either a GIMPLE_CALL returning a value, or just a plain |
5343 return; | 5346 return; |
5344 } | 5347 } |
5345 | 5348 |
5346 /* For callees without function info (that's external functions), | 5349 /* For callees without function info (that's external functions), |
5347 ESCAPED is clobbered and used. */ | 5350 ESCAPED is clobbered and used. */ |
5348 if (gimple_call_fndecl (t) | 5351 if (cfi->decl |
5352 && TREE_CODE (cfi->decl) == FUNCTION_DECL | |
5349 && !cfi->is_fn_info) | 5353 && !cfi->is_fn_info) |
5350 { | 5354 { |
5351 varinfo_t vi; | 5355 varinfo_t vi; |
5352 | 5356 |
5353 if (gimple_vdef (t)) | 5357 if (gimple_vdef (t)) |
5928 | 5932 |
5929 /* Create a varinfo structure for NAME and DECL, and add it to VARMAP. | 5933 /* Create a varinfo structure for NAME and DECL, and add it to VARMAP. |
5930 This will also create any varinfo structures necessary for fields | 5934 This will also create any varinfo structures necessary for fields |
5931 of DECL. DECL is a function parameter if HANDLE_PARAM is set. | 5935 of DECL. DECL is a function parameter if HANDLE_PARAM is set. |
5932 HANDLED_STRUCT_TYPE is used to register struct types reached by following | 5936 HANDLED_STRUCT_TYPE is used to register struct types reached by following |
5933 restrict pointers. This is needed to prevent infinite recursion. */ | 5937 restrict pointers. This is needed to prevent infinite recursion. |
5938 If ADD_RESTRICT, pretend that the pointer NAME is restrict even if DECL | |
5939 does not advertise it. */ | |
5934 | 5940 |
5935 static varinfo_t | 5941 static varinfo_t |
5936 create_variable_info_for_1 (tree decl, const char *name, bool add_id, | 5942 create_variable_info_for_1 (tree decl, const char *name, bool add_id, |
5937 bool handle_param, bitmap handled_struct_type) | 5943 bool handle_param, bitmap handled_struct_type, |
5944 bool add_restrict = false) | |
5938 { | 5945 { |
5939 varinfo_t vi, newvi; | 5946 varinfo_t vi, newvi; |
5940 tree decl_type = TREE_TYPE (decl); | 5947 tree decl_type = TREE_TYPE (decl); |
5941 tree declsize = DECL_P (decl) ? DECL_SIZE (decl) : TYPE_SIZE (decl_type); | 5948 tree declsize = DECL_P (decl) ? DECL_SIZE (decl) : TYPE_SIZE (decl_type); |
5942 auto_vec<fieldoff_s> fieldstack; | 5949 auto_vec<fieldoff_s> fieldstack; |
6006 vi->may_have_pointers = true; | 6013 vi->may_have_pointers = true; |
6007 vi->fullsize = tree_to_uhwi (declsize); | 6014 vi->fullsize = tree_to_uhwi (declsize); |
6008 vi->size = vi->fullsize; | 6015 vi->size = vi->fullsize; |
6009 vi->is_full_var = true; | 6016 vi->is_full_var = true; |
6010 if (POINTER_TYPE_P (decl_type) | 6017 if (POINTER_TYPE_P (decl_type) |
6011 && TYPE_RESTRICT (decl_type)) | 6018 && (TYPE_RESTRICT (decl_type) || add_restrict)) |
6012 vi->only_restrict_pointers = 1; | 6019 vi->only_restrict_pointers = 1; |
6013 if (vi->only_restrict_pointers | 6020 if (vi->only_restrict_pointers |
6014 && !type_contains_placeholder_p (TREE_TYPE (decl_type)) | 6021 && !type_contains_placeholder_p (TREE_TYPE (decl_type)) |
6015 && handle_param | 6022 && handle_param |
6016 && !bitmap_bit_p (handled_struct_type, | 6023 && !bitmap_bit_p (handled_struct_type, |
6103 } | 6110 } |
6104 | 6111 |
6105 static unsigned int | 6112 static unsigned int |
6106 create_variable_info_for (tree decl, const char *name, bool add_id) | 6113 create_variable_info_for (tree decl, const char *name, bool add_id) |
6107 { | 6114 { |
6115 /* First see if we are dealing with an ifunc resolver call and | |
6116 assiociate that with a call to the resolver function result. */ | |
6117 cgraph_node *node; | |
6118 if (in_ipa_mode | |
6119 && TREE_CODE (decl) == FUNCTION_DECL | |
6120 && (node = cgraph_node::get (decl)) | |
6121 && node->ifunc_resolver) | |
6122 { | |
6123 varinfo_t fi = get_vi_for_tree (node->get_alias_target ()->decl); | |
6124 constraint_expr rhs | |
6125 = get_function_part_constraint (fi, fi_result); | |
6126 fi = new_var_info (NULL_TREE, "ifuncres", true); | |
6127 fi->is_reg_var = true; | |
6128 constraint_expr lhs; | |
6129 lhs.type = SCALAR; | |
6130 lhs.var = fi->id; | |
6131 lhs.offset = 0; | |
6132 process_constraint (new_constraint (lhs, rhs)); | |
6133 insert_vi_for_tree (decl, fi); | |
6134 return fi->id; | |
6135 } | |
6136 | |
6108 varinfo_t vi = create_variable_info_for_1 (decl, name, add_id, false, NULL); | 6137 varinfo_t vi = create_variable_info_for_1 (decl, name, add_id, false, NULL); |
6109 unsigned int id = vi->id; | 6138 unsigned int id = vi->id; |
6110 | 6139 |
6111 insert_vi_for_tree (decl, vi); | 6140 insert_vi_for_tree (decl, vi); |
6112 | 6141 |
6235 static void | 6264 static void |
6236 intra_create_variable_infos (struct function *fn) | 6265 intra_create_variable_infos (struct function *fn) |
6237 { | 6266 { |
6238 tree t; | 6267 tree t; |
6239 bitmap handled_struct_type = NULL; | 6268 bitmap handled_struct_type = NULL; |
6269 bool this_parm_in_ctor = DECL_CXX_CONSTRUCTOR_P (fn->decl); | |
6240 | 6270 |
6241 /* For each incoming pointer argument arg, create the constraint ARG | 6271 /* For each incoming pointer argument arg, create the constraint ARG |
6242 = NONLOCAL or a dummy variable if it is a restrict qualified | 6272 = NONLOCAL or a dummy variable if it is a restrict qualified |
6243 passed-by-reference argument. */ | 6273 passed-by-reference argument. */ |
6244 for (t = DECL_ARGUMENTS (fn->decl); t; t = DECL_CHAIN (t)) | 6274 for (t = DECL_ARGUMENTS (fn->decl); t; t = DECL_CHAIN (t)) |
6246 if (handled_struct_type == NULL) | 6276 if (handled_struct_type == NULL) |
6247 handled_struct_type = BITMAP_ALLOC (NULL); | 6277 handled_struct_type = BITMAP_ALLOC (NULL); |
6248 | 6278 |
6249 varinfo_t p | 6279 varinfo_t p |
6250 = create_variable_info_for_1 (t, alias_get_name (t), false, true, | 6280 = create_variable_info_for_1 (t, alias_get_name (t), false, true, |
6251 handled_struct_type); | 6281 handled_struct_type, this_parm_in_ctor); |
6252 insert_vi_for_tree (t, p); | 6282 insert_vi_for_tree (t, p); |
6253 | 6283 |
6254 make_param_constraints (p); | 6284 make_param_constraints (p); |
6285 | |
6286 this_parm_in_ctor = false; | |
6255 } | 6287 } |
6256 | 6288 |
6257 if (handled_struct_type != NULL) | 6289 if (handled_struct_type != NULL) |
6258 BITMAP_FREE (handled_struct_type); | 6290 BITMAP_FREE (handled_struct_type); |
6259 | 6291 |
7363 } | 7395 } |
7364 | 7396 |
7365 struct vls_data | 7397 struct vls_data |
7366 { | 7398 { |
7367 unsigned short clique; | 7399 unsigned short clique; |
7400 bool escaped_p; | |
7368 bitmap rvars; | 7401 bitmap rvars; |
7369 }; | 7402 }; |
7370 | 7403 |
7371 /* Mark "other" loads and stores as belonging to CLIQUE and with | 7404 /* Mark "other" loads and stores as belonging to CLIQUE and with |
7372 base zero. */ | 7405 base zero. */ |
7374 static bool | 7407 static bool |
7375 visit_loadstore (gimple *, tree base, tree ref, void *data) | 7408 visit_loadstore (gimple *, tree base, tree ref, void *data) |
7376 { | 7409 { |
7377 unsigned short clique = ((vls_data *) data)->clique; | 7410 unsigned short clique = ((vls_data *) data)->clique; |
7378 bitmap rvars = ((vls_data *) data)->rvars; | 7411 bitmap rvars = ((vls_data *) data)->rvars; |
7412 bool escaped_p = ((vls_data *) data)->escaped_p; | |
7379 if (TREE_CODE (base) == MEM_REF | 7413 if (TREE_CODE (base) == MEM_REF |
7380 || TREE_CODE (base) == TARGET_MEM_REF) | 7414 || TREE_CODE (base) == TARGET_MEM_REF) |
7381 { | 7415 { |
7382 tree ptr = TREE_OPERAND (base, 0); | 7416 tree ptr = TREE_OPERAND (base, 0); |
7383 if (TREE_CODE (ptr) == SSA_NAME) | 7417 if (TREE_CODE (ptr) == SSA_NAME) |
7394 varinfo_t vi = lookup_vi_for_tree (ptr); | 7428 varinfo_t vi = lookup_vi_for_tree (ptr); |
7395 if (! vi) | 7429 if (! vi) |
7396 return false; | 7430 return false; |
7397 | 7431 |
7398 vi = get_varinfo (find (vi->id)); | 7432 vi = get_varinfo (find (vi->id)); |
7399 if (bitmap_intersect_p (rvars, vi->solution)) | 7433 if (bitmap_intersect_p (rvars, vi->solution) |
7434 || (escaped_p && bitmap_bit_p (vi->solution, escaped_id))) | |
7400 return false; | 7435 return false; |
7401 } | 7436 } |
7402 | 7437 |
7403 /* Do not overwrite existing cliques (that includes clique, base | 7438 /* Do not overwrite existing cliques (that includes clique, base |
7404 pairs we just set). */ | 7439 pairs we just set). */ |
7429 } | 7464 } |
7430 | 7465 |
7431 return false; | 7466 return false; |
7432 } | 7467 } |
7433 | 7468 |
7434 /* If REF is a MEM_REF then assign a clique, base pair to it, updating | 7469 struct msdi_data { |
7435 CLIQUE, *RESTRICT_VAR and LAST_RUID. Return whether dependence info | 7470 tree ptr; |
7436 was assigned to REF. */ | 7471 unsigned short *clique; |
7472 unsigned short *last_ruid; | |
7473 varinfo_t restrict_var; | |
7474 }; | |
7475 | |
7476 /* If BASE is a MEM_REF then assign a clique, base pair to it, updating | |
7477 CLIQUE, *RESTRICT_VAR and LAST_RUID as passed via DATA. | |
7478 Return whether dependence info was assigned to BASE. */ | |
7437 | 7479 |
7438 static bool | 7480 static bool |
7439 maybe_set_dependence_info (tree ref, tree ptr, | 7481 maybe_set_dependence_info (gimple *, tree base, tree, void *data) |
7440 unsigned short &clique, varinfo_t restrict_var, | 7482 { |
7441 unsigned short &last_ruid) | 7483 tree ptr = ((msdi_data *)data)->ptr; |
7442 { | 7484 unsigned short &clique = *((msdi_data *)data)->clique; |
7443 while (handled_component_p (ref)) | 7485 unsigned short &last_ruid = *((msdi_data *)data)->last_ruid; |
7444 ref = TREE_OPERAND (ref, 0); | 7486 varinfo_t restrict_var = ((msdi_data *)data)->restrict_var; |
7445 if ((TREE_CODE (ref) == MEM_REF | 7487 if ((TREE_CODE (base) == MEM_REF |
7446 || TREE_CODE (ref) == TARGET_MEM_REF) | 7488 || TREE_CODE (base) == TARGET_MEM_REF) |
7447 && TREE_OPERAND (ref, 0) == ptr) | 7489 && TREE_OPERAND (base, 0) == ptr) |
7448 { | 7490 { |
7449 /* Do not overwrite existing cliques. This avoids overwriting dependence | 7491 /* Do not overwrite existing cliques. This avoids overwriting dependence |
7450 info inlined from a function with restrict parameters inlined | 7492 info inlined from a function with restrict parameters inlined |
7451 into a function with restrict parameters. This usually means we | 7493 into a function with restrict parameters. This usually means we |
7452 prefer to be precise in innermost loops. */ | 7494 prefer to be precise in innermost loops. */ |
7453 if (MR_DEPENDENCE_CLIQUE (ref) == 0) | 7495 if (MR_DEPENDENCE_CLIQUE (base) == 0) |
7454 { | 7496 { |
7455 if (clique == 0) | 7497 if (clique == 0) |
7456 clique = ++cfun->last_clique; | 7498 clique = ++cfun->last_clique; |
7457 if (restrict_var->ruid == 0) | 7499 if (restrict_var->ruid == 0) |
7458 restrict_var->ruid = ++last_ruid; | 7500 restrict_var->ruid = ++last_ruid; |
7459 MR_DEPENDENCE_CLIQUE (ref) = clique; | 7501 MR_DEPENDENCE_CLIQUE (base) = clique; |
7460 MR_DEPENDENCE_BASE (ref) = restrict_var->ruid; | 7502 MR_DEPENDENCE_BASE (base) = restrict_var->ruid; |
7461 return true; | 7503 return true; |
7462 } | 7504 } |
7463 } | 7505 } |
7464 return false; | 7506 return false; |
7465 } | 7507 } |
7471 compute_dependence_clique (void) | 7513 compute_dependence_clique (void) |
7472 { | 7514 { |
7473 unsigned short clique = 0; | 7515 unsigned short clique = 0; |
7474 unsigned short last_ruid = 0; | 7516 unsigned short last_ruid = 0; |
7475 bitmap rvars = BITMAP_ALLOC (NULL); | 7517 bitmap rvars = BITMAP_ALLOC (NULL); |
7518 bool escaped_p = false; | |
7476 for (unsigned i = 0; i < num_ssa_names; ++i) | 7519 for (unsigned i = 0; i < num_ssa_names; ++i) |
7477 { | 7520 { |
7478 tree ptr = ssa_name (i); | 7521 tree ptr = ssa_name (i); |
7479 if (!ptr || !POINTER_TYPE_P (TREE_TYPE (ptr))) | 7522 if (!ptr || !POINTER_TYPE_P (TREE_TYPE (ptr))) |
7480 continue; | 7523 continue; |
7527 { | 7570 { |
7528 /* Now look at possible dereferences of ptr. */ | 7571 /* Now look at possible dereferences of ptr. */ |
7529 imm_use_iterator ui; | 7572 imm_use_iterator ui; |
7530 gimple *use_stmt; | 7573 gimple *use_stmt; |
7531 bool used = false; | 7574 bool used = false; |
7575 msdi_data data = { ptr, &clique, &last_ruid, restrict_var }; | |
7532 FOR_EACH_IMM_USE_STMT (use_stmt, ui, ptr) | 7576 FOR_EACH_IMM_USE_STMT (use_stmt, ui, ptr) |
7577 used |= walk_stmt_load_store_ops (use_stmt, &data, | |
7578 maybe_set_dependence_info, | |
7579 maybe_set_dependence_info); | |
7580 if (used) | |
7533 { | 7581 { |
7534 /* ??? Calls and asms. */ | 7582 bitmap_set_bit (rvars, restrict_var->id); |
7535 if (!gimple_assign_single_p (use_stmt)) | 7583 varinfo_t escaped = get_varinfo (find (escaped_id)); |
7536 continue; | 7584 if (bitmap_bit_p (escaped->solution, restrict_var->id)) |
7537 used |= maybe_set_dependence_info (gimple_assign_lhs (use_stmt), | 7585 escaped_p = true; |
7538 ptr, clique, restrict_var, | |
7539 last_ruid); | |
7540 used |= maybe_set_dependence_info (gimple_assign_rhs1 (use_stmt), | |
7541 ptr, clique, restrict_var, | |
7542 last_ruid); | |
7543 } | 7586 } |
7544 if (used) | |
7545 bitmap_set_bit (rvars, restrict_var->id); | |
7546 } | 7587 } |
7547 } | 7588 } |
7548 | 7589 |
7549 if (clique != 0) | 7590 if (clique != 0) |
7550 { | 7591 { |
7553 accesses but not against each other. */ | 7594 accesses but not against each other. */ |
7554 /* ??? For restricts derived from globals (thus not incoming | 7595 /* ??? For restricts derived from globals (thus not incoming |
7555 parameters) we can't restrict scoping properly thus the following | 7596 parameters) we can't restrict scoping properly thus the following |
7556 is too aggressive there. For now we have excluded those globals from | 7597 is too aggressive there. For now we have excluded those globals from |
7557 getting into the MR_DEPENDENCE machinery. */ | 7598 getting into the MR_DEPENDENCE machinery. */ |
7558 vls_data data = { clique, rvars }; | 7599 vls_data data = { clique, escaped_p, rvars }; |
7559 basic_block bb; | 7600 basic_block bb; |
7560 FOR_EACH_BB_FN (bb, cfun) | 7601 FOR_EACH_BB_FN (bb, cfun) |
7561 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); | 7602 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); |
7562 !gsi_end_p (gsi); gsi_next (&gsi)) | 7603 !gsi_end_p (gsi); gsi_next (&gsi)) |
7563 { | 7604 { |
7700 associate_varinfo_to_alias (struct cgraph_node *node, void *data) | 7741 associate_varinfo_to_alias (struct cgraph_node *node, void *data) |
7701 { | 7742 { |
7702 if ((node->alias | 7743 if ((node->alias |
7703 || (node->thunk.thunk_p | 7744 || (node->thunk.thunk_p |
7704 && ! node->global.inlined_to)) | 7745 && ! node->global.inlined_to)) |
7705 && node->analyzed) | 7746 && node->analyzed |
7747 && !node->ifunc_resolver) | |
7706 insert_vi_for_tree (node->decl, (varinfo_t)data); | 7748 insert_vi_for_tree (node->decl, (varinfo_t)data); |
7707 return false; | 7749 return false; |
7708 } | 7750 } |
7709 | 7751 |
7710 /* Dump varinfo VI to FILE. */ | 7752 /* Dump varinfo VI to FILE. */ |
8072 *gimple_call_use_set (stmt) | 8114 *gimple_call_use_set (stmt) |
8073 = find_what_var_points_to | 8115 = find_what_var_points_to |
8074 (node->decl, first_vi_for_offset (fi, fi_uses)); | 8116 (node->decl, first_vi_for_offset (fi, fi_uses)); |
8075 } | 8117 } |
8076 /* Handle direct calls to external functions. */ | 8118 /* Handle direct calls to external functions. */ |
8077 else if (decl) | 8119 else if (decl && (!fi || fi->decl)) |
8078 { | 8120 { |
8079 pt = gimple_call_use_set (stmt); | 8121 pt = gimple_call_use_set (stmt); |
8080 if (gimple_call_flags (stmt) & ECF_CONST) | 8122 if (gimple_call_flags (stmt) & ECF_CONST) |
8081 memset (pt, 0, sizeof (struct pt_solution)); | 8123 memset (pt, 0, sizeof (struct pt_solution)); |
8082 else if ((vi = lookup_call_use_vi (stmt)) != NULL) | 8124 else if ((vi = lookup_call_use_vi (stmt)) != NULL) |
8117 *pt = ipa_escaped_pt; | 8159 *pt = ipa_escaped_pt; |
8118 pt->nonlocal = 1; | 8160 pt->nonlocal = 1; |
8119 } | 8161 } |
8120 } | 8162 } |
8121 /* Handle indirect calls. */ | 8163 /* Handle indirect calls. */ |
8122 else if (!decl | 8164 else if ((fi = get_fi_for_callee (stmt))) |
8123 && (fi = get_fi_for_callee (stmt))) | |
8124 { | 8165 { |
8125 /* We need to accumulate all clobbers/uses of all possible | 8166 /* We need to accumulate all clobbers/uses of all possible |
8126 callees. */ | 8167 callees. */ |
8127 fi = get_varinfo (find (fi->id)); | 8168 fi = get_varinfo (find (fi->id)); |
8128 /* If we cannot constrain the set of functions we'll end up | 8169 /* If we cannot constrain the set of functions we'll end up |
8174 pt_solution_ior_into (clobbers, &sol); | 8215 pt_solution_ior_into (clobbers, &sol); |
8175 } | 8216 } |
8176 } | 8217 } |
8177 } | 8218 } |
8178 } | 8219 } |
8220 else | |
8221 gcc_unreachable (); | |
8179 } | 8222 } |
8180 } | 8223 } |
8181 | 8224 |
8182 fn->gimple_df->ipa_pta = true; | 8225 fn->gimple_df->ipa_pta = true; |
8183 | 8226 |