Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-ssa-structalias.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
comparison
equal
deleted
inserted
replaced
131:84e7813d76e9 | 145:1830386684a0 |
---|---|
1 /* Tree based points-to analysis | 1 /* Tree based points-to analysis |
2 Copyright (C) 2005-2018 Free Software Foundation, Inc. | 2 Copyright (C) 2005-2020 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 |
35 #include "stor-layout.h" | 35 #include "stor-layout.h" |
36 #include "stmt.h" | 36 #include "stmt.h" |
37 #include "gimple-iterator.h" | 37 #include "gimple-iterator.h" |
38 #include "tree-into-ssa.h" | 38 #include "tree-into-ssa.h" |
39 #include "tree-dfa.h" | 39 #include "tree-dfa.h" |
40 #include "params.h" | |
41 #include "gimple-walk.h" | 40 #include "gimple-walk.h" |
42 #include "varasm.h" | 41 #include "varasm.h" |
43 #include "stringpool.h" | 42 #include "stringpool.h" |
44 #include "attribs.h" | 43 #include "attribs.h" |
45 #include "tree-ssa.h" | 44 #include "tree-ssa.h" |
45 #include "tree-cfg.h" | |
46 | 46 |
47 /* 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 |
48 program, then solve the resulting constraints in order to generate the | 48 program, then solve the resulting constraints in order to generate the |
49 points-to sets. | 49 points-to sets. |
50 | 50 |
296 /* Size of the variable, in bits. */ | 296 /* Size of the variable, in bits. */ |
297 unsigned HOST_WIDE_INT size; | 297 unsigned HOST_WIDE_INT size; |
298 | 298 |
299 /* Full size of the base variable, in bits. */ | 299 /* Full size of the base variable, in bits. */ |
300 unsigned HOST_WIDE_INT fullsize; | 300 unsigned HOST_WIDE_INT fullsize; |
301 | |
302 /* In IPA mode the shadow UID in case the variable needs to be duplicated in | |
303 the final points-to solution because it reaches its containing | |
304 function recursively. Zero if none is needed. */ | |
305 unsigned int shadow_var_uid; | |
301 | 306 |
302 /* Name of this variable */ | 307 /* Name of this variable */ |
303 const char *name; | 308 const char *name; |
304 | 309 |
305 /* Tree that this variable is associated with. */ | 310 /* Tree that this variable is associated with. */ |
395 || (VAR_P (t) && DECL_HARD_REGISTER (t))); | 400 || (VAR_P (t) && DECL_HARD_REGISTER (t))); |
396 ret->is_reg_var = (t && TREE_CODE (t) == SSA_NAME); | 401 ret->is_reg_var = (t && TREE_CODE (t) == SSA_NAME); |
397 ret->solution = BITMAP_ALLOC (&pta_obstack); | 402 ret->solution = BITMAP_ALLOC (&pta_obstack); |
398 ret->oldsolution = NULL; | 403 ret->oldsolution = NULL; |
399 ret->next = 0; | 404 ret->next = 0; |
405 ret->shadow_var_uid = 0; | |
400 ret->head = ret->id; | 406 ret->head = ret->id; |
401 | 407 |
402 stats.total_vars++; | 408 stats.total_vars++; |
403 | 409 |
404 varmap.safe_push (ret); | 410 varmap.safe_push (ret); |
1384 /* Changed variables on the last iteration. */ | 1390 /* Changed variables on the last iteration. */ |
1385 static bitmap changed; | 1391 static bitmap changed; |
1386 | 1392 |
1387 /* Strongly Connected Component visitation info. */ | 1393 /* Strongly Connected Component visitation info. */ |
1388 | 1394 |
1389 struct scc_info | 1395 class scc_info |
1390 { | 1396 { |
1397 public: | |
1391 scc_info (size_t size); | 1398 scc_info (size_t size); |
1392 ~scc_info (); | 1399 ~scc_info (); |
1393 | 1400 |
1394 auto_sbitmap visited; | 1401 auto_sbitmap visited; |
1395 auto_sbitmap deleted; | 1402 auto_sbitmap deleted; |
1410 connected components in a directed graph" by Esko Nuutila and Eljas | 1417 connected components in a directed graph" by Esko Nuutila and Eljas |
1411 Soisalon-Soininen, in Information Processing Letters volume 49, | 1418 Soisalon-Soininen, in Information Processing Letters volume 49, |
1412 number 1, pages 9-14. */ | 1419 number 1, pages 9-14. */ |
1413 | 1420 |
1414 static void | 1421 static void |
1415 scc_visit (constraint_graph_t graph, struct scc_info *si, unsigned int n) | 1422 scc_visit (constraint_graph_t graph, class scc_info *si, unsigned int n) |
1416 { | 1423 { |
1417 unsigned int i; | 1424 unsigned int i; |
1418 bitmap_iterator bi; | 1425 bitmap_iterator bi; |
1419 unsigned int my_dfs; | 1426 unsigned int my_dfs; |
1420 | 1427 |
1902 } *equiv_class_label_t; | 1909 } *equiv_class_label_t; |
1903 typedef const struct equiv_class_label *const_equiv_class_label_t; | 1910 typedef const struct equiv_class_label *const_equiv_class_label_t; |
1904 | 1911 |
1905 /* Equiv_class_label hashtable helpers. */ | 1912 /* Equiv_class_label hashtable helpers. */ |
1906 | 1913 |
1907 struct equiv_class_hasher : free_ptr_hash <equiv_class_label> | 1914 struct equiv_class_hasher : nofree_ptr_hash <equiv_class_label> |
1908 { | 1915 { |
1909 static inline hashval_t hash (const equiv_class_label *); | 1916 static inline hashval_t hash (const equiv_class_label *); |
1910 static inline bool equal (const equiv_class_label *, | 1917 static inline bool equal (const equiv_class_label *, |
1911 const equiv_class_label *); | 1918 const equiv_class_label *); |
1912 }; | 1919 }; |
1935 | 1942 |
1936 /* A hashtable for mapping a bitmap of labels->location equivalence | 1943 /* A hashtable for mapping a bitmap of labels->location equivalence |
1937 classes. */ | 1944 classes. */ |
1938 static hash_table<equiv_class_hasher> *location_equiv_class_table; | 1945 static hash_table<equiv_class_hasher> *location_equiv_class_table; |
1939 | 1946 |
1947 struct obstack equiv_class_obstack; | |
1948 | |
1940 /* Lookup a equivalence class in TABLE by the bitmap of LABELS with | 1949 /* Lookup a equivalence class in TABLE by the bitmap of LABELS with |
1941 hash HAS it contains. Sets *REF_LABELS to the bitmap LABELS | 1950 hash HAS it contains. Sets *REF_LABELS to the bitmap LABELS |
1942 is equivalent to. */ | 1951 is equivalent to. */ |
1943 | 1952 |
1944 static equiv_class_label * | 1953 static equiv_class_label * |
1951 ecl.labels = labels; | 1960 ecl.labels = labels; |
1952 ecl.hashcode = bitmap_hash (labels); | 1961 ecl.hashcode = bitmap_hash (labels); |
1953 slot = table->find_slot (&ecl, INSERT); | 1962 slot = table->find_slot (&ecl, INSERT); |
1954 if (!*slot) | 1963 if (!*slot) |
1955 { | 1964 { |
1956 *slot = XNEW (struct equiv_class_label); | 1965 *slot = XOBNEW (&equiv_class_obstack, struct equiv_class_label); |
1957 (*slot)->labels = labels; | 1966 (*slot)->labels = labels; |
1958 (*slot)->hashcode = ecl.hashcode; | 1967 (*slot)->hashcode = ecl.hashcode; |
1959 (*slot)->equivalence_class = 0; | 1968 (*slot)->equivalence_class = 0; |
1960 } | 1969 } |
1961 | 1970 |
2013 | 2022 |
2014 /* Recursive routine to find strongly connected components in GRAPH, | 2023 /* Recursive routine to find strongly connected components in GRAPH, |
2015 and label it's nodes with DFS numbers. */ | 2024 and label it's nodes with DFS numbers. */ |
2016 | 2025 |
2017 static void | 2026 static void |
2018 condense_visit (constraint_graph_t graph, struct scc_info *si, unsigned int n) | 2027 condense_visit (constraint_graph_t graph, class scc_info *si, unsigned int n) |
2019 { | 2028 { |
2020 unsigned int i; | 2029 unsigned int i; |
2021 bitmap_iterator bi; | 2030 bitmap_iterator bi; |
2022 unsigned int my_dfs; | 2031 unsigned int my_dfs; |
2023 | 2032 |
2061 } | 2070 } |
2062 | 2071 |
2063 /* See if any components have been identified. */ | 2072 /* See if any components have been identified. */ |
2064 if (si->dfs[n] == my_dfs) | 2073 if (si->dfs[n] == my_dfs) |
2065 { | 2074 { |
2066 while (si->scc_stack.length () != 0 | 2075 if (si->scc_stack.length () != 0 |
2067 && si->dfs[si->scc_stack.last ()] >= my_dfs) | 2076 && si->dfs[si->scc_stack.last ()] >= my_dfs) |
2068 { | 2077 { |
2069 unsigned int w = si->scc_stack.pop (); | 2078 /* Find the first node of the SCC and do non-bitmap work. */ |
2070 si->node_mapping[w] = n; | 2079 bool direct_p = true; |
2071 | 2080 unsigned first = si->scc_stack.length (); |
2072 if (!bitmap_bit_p (graph->direct_nodes, w)) | 2081 do |
2082 { | |
2083 --first; | |
2084 unsigned int w = si->scc_stack[first]; | |
2085 si->node_mapping[w] = n; | |
2086 if (!bitmap_bit_p (graph->direct_nodes, w)) | |
2087 direct_p = false; | |
2088 } | |
2089 while (first > 0 | |
2090 && si->dfs[si->scc_stack[first - 1]] >= my_dfs); | |
2091 if (!direct_p) | |
2073 bitmap_clear_bit (graph->direct_nodes, n); | 2092 bitmap_clear_bit (graph->direct_nodes, n); |
2074 | 2093 |
2075 /* Unify our nodes. */ | 2094 /* Want to reduce to node n, push that first. */ |
2076 if (graph->preds[w]) | 2095 si->scc_stack.reserve (1); |
2096 si->scc_stack.quick_push (si->scc_stack[first]); | |
2097 si->scc_stack[first] = n; | |
2098 | |
2099 unsigned scc_size = si->scc_stack.length () - first; | |
2100 unsigned split = scc_size / 2; | |
2101 unsigned carry = scc_size - split * 2; | |
2102 while (split > 0) | |
2077 { | 2103 { |
2078 if (!graph->preds[n]) | 2104 for (unsigned i = 0; i < split; ++i) |
2079 graph->preds[n] = BITMAP_ALLOC (&predbitmap_obstack); | 2105 { |
2080 bitmap_ior_into (graph->preds[n], graph->preds[w]); | 2106 unsigned a = si->scc_stack[first + i]; |
2107 unsigned b = si->scc_stack[first + split + carry + i]; | |
2108 | |
2109 /* Unify our nodes. */ | |
2110 if (graph->preds[b]) | |
2111 { | |
2112 if (!graph->preds[a]) | |
2113 std::swap (graph->preds[a], graph->preds[b]); | |
2114 else | |
2115 bitmap_ior_into_and_free (graph->preds[a], | |
2116 &graph->preds[b]); | |
2117 } | |
2118 if (graph->implicit_preds[b]) | |
2119 { | |
2120 if (!graph->implicit_preds[a]) | |
2121 std::swap (graph->implicit_preds[a], | |
2122 graph->implicit_preds[b]); | |
2123 else | |
2124 bitmap_ior_into_and_free (graph->implicit_preds[a], | |
2125 &graph->implicit_preds[b]); | |
2126 } | |
2127 if (graph->points_to[b]) | |
2128 { | |
2129 if (!graph->points_to[a]) | |
2130 std::swap (graph->points_to[a], graph->points_to[b]); | |
2131 else | |
2132 bitmap_ior_into_and_free (graph->points_to[a], | |
2133 &graph->points_to[b]); | |
2134 } | |
2135 } | |
2136 unsigned remain = split + carry; | |
2137 split = remain / 2; | |
2138 carry = remain - split * 2; | |
2081 } | 2139 } |
2082 if (graph->implicit_preds[w]) | 2140 /* Actually pop the SCC. */ |
2083 { | 2141 si->scc_stack.truncate (first); |
2084 if (!graph->implicit_preds[n]) | |
2085 graph->implicit_preds[n] = BITMAP_ALLOC (&predbitmap_obstack); | |
2086 bitmap_ior_into (graph->implicit_preds[n], | |
2087 graph->implicit_preds[w]); | |
2088 } | |
2089 if (graph->points_to[w]) | |
2090 { | |
2091 if (!graph->points_to[n]) | |
2092 graph->points_to[n] = BITMAP_ALLOC (&predbitmap_obstack); | |
2093 bitmap_ior_into (graph->points_to[n], | |
2094 graph->points_to[w]); | |
2095 } | |
2096 } | 2142 } |
2097 bitmap_set_bit (si->deleted, n); | 2143 bitmap_set_bit (si->deleted, n); |
2098 } | 2144 } |
2099 else | 2145 else |
2100 si->scc_stack.safe_push (n); | 2146 si->scc_stack.safe_push (n); |
2118 2. The end result of a given set of operations must be unique iff the | 2164 2. The end result of a given set of operations must be unique iff the |
2119 combination of input values is unique | 2165 combination of input values is unique |
2120 3. Hashable. */ | 2166 3. Hashable. */ |
2121 | 2167 |
2122 static void | 2168 static void |
2123 label_visit (constraint_graph_t graph, struct scc_info *si, unsigned int n) | 2169 label_visit (constraint_graph_t graph, class scc_info *si, unsigned int n) |
2124 { | 2170 { |
2125 unsigned int i, first_pred; | 2171 unsigned int i, first_pred; |
2126 bitmap_iterator bi; | 2172 bitmap_iterator bi; |
2127 | 2173 |
2128 bitmap_set_bit (si->visited, n); | 2174 bitmap_set_bit (si->visited, n); |
2205 } | 2251 } |
2206 | 2252 |
2207 /* Print the pred graph in dot format. */ | 2253 /* Print the pred graph in dot format. */ |
2208 | 2254 |
2209 static void | 2255 static void |
2210 dump_pred_graph (struct scc_info *si, FILE *file) | 2256 dump_pred_graph (class scc_info *si, FILE *file) |
2211 { | 2257 { |
2212 unsigned int i; | 2258 unsigned int i; |
2213 | 2259 |
2214 /* Only print the graph if it has already been initialized: */ | 2260 /* Only print the graph if it has already been initialized: */ |
2215 if (!graph) | 2261 if (!graph) |
2280 } | 2326 } |
2281 | 2327 |
2282 /* Perform offline variable substitution, discovering equivalence | 2328 /* Perform offline variable substitution, discovering equivalence |
2283 classes, and eliminating non-pointer variables. */ | 2329 classes, and eliminating non-pointer variables. */ |
2284 | 2330 |
2285 static struct scc_info * | 2331 static class scc_info * |
2286 perform_var_substitution (constraint_graph_t graph) | 2332 perform_var_substitution (constraint_graph_t graph) |
2287 { | 2333 { |
2288 unsigned int i; | 2334 unsigned int i; |
2289 unsigned int size = graph->size; | 2335 unsigned int size = graph->size; |
2290 scc_info *si = new scc_info (size); | 2336 scc_info *si = new scc_info (size); |
2291 | 2337 |
2292 bitmap_obstack_initialize (&iteration_obstack); | 2338 bitmap_obstack_initialize (&iteration_obstack); |
2339 gcc_obstack_init (&equiv_class_obstack); | |
2293 pointer_equiv_class_table = new hash_table<equiv_class_hasher> (511); | 2340 pointer_equiv_class_table = new hash_table<equiv_class_hasher> (511); |
2294 location_equiv_class_table | 2341 location_equiv_class_table |
2295 = new hash_table<equiv_class_hasher> (511); | 2342 = new hash_table<equiv_class_hasher> (511); |
2296 pointer_equiv_class = 1; | 2343 pointer_equiv_class = 1; |
2297 location_equiv_class = 1; | 2344 location_equiv_class = 1; |
2414 | 2461 |
2415 /* Free information that was only necessary for variable | 2462 /* Free information that was only necessary for variable |
2416 substitution. */ | 2463 substitution. */ |
2417 | 2464 |
2418 static void | 2465 static void |
2419 free_var_substitution_info (struct scc_info *si) | 2466 free_var_substitution_info (class scc_info *si) |
2420 { | 2467 { |
2421 delete si; | 2468 delete si; |
2422 free (graph->pointer_label); | 2469 free (graph->pointer_label); |
2423 free (graph->loc_label); | 2470 free (graph->loc_label); |
2424 free (graph->pointed_by); | 2471 free (graph->pointed_by); |
2427 sbitmap_free (graph->direct_nodes); | 2474 sbitmap_free (graph->direct_nodes); |
2428 delete pointer_equiv_class_table; | 2475 delete pointer_equiv_class_table; |
2429 pointer_equiv_class_table = NULL; | 2476 pointer_equiv_class_table = NULL; |
2430 delete location_equiv_class_table; | 2477 delete location_equiv_class_table; |
2431 location_equiv_class_table = NULL; | 2478 location_equiv_class_table = NULL; |
2479 obstack_free (&equiv_class_obstack, NULL); | |
2432 bitmap_obstack_release (&iteration_obstack); | 2480 bitmap_obstack_release (&iteration_obstack); |
2433 } | 2481 } |
2434 | 2482 |
2435 /* Return an existing node that is equivalent to NODE, which has | 2483 /* Return an existing node that is equivalent to NODE, which has |
2436 equivalence class LABEL, if one exists. Return NODE otherwise. */ | 2484 equivalence class LABEL, if one exists. Return NODE otherwise. */ |
2538 collapsing of equivalent nodes. SI is the SCC_INFO that is the | 2586 collapsing of equivalent nodes. SI is the SCC_INFO that is the |
2539 result of perform_variable_substitution. */ | 2587 result of perform_variable_substitution. */ |
2540 | 2588 |
2541 static void | 2589 static void |
2542 rewrite_constraints (constraint_graph_t graph, | 2590 rewrite_constraints (constraint_graph_t graph, |
2543 struct scc_info *si) | 2591 class scc_info *si) |
2544 { | 2592 { |
2545 int i; | 2593 int i; |
2546 constraint_t c; | 2594 constraint_t c; |
2547 | 2595 |
2548 if (flag_checking) | 2596 if (flag_checking) |
3242 result.offset = 0; | 3290 result.offset = 0; |
3243 results->safe_push (result); | 3291 results->safe_push (result); |
3244 return; | 3292 return; |
3245 } | 3293 } |
3246 | 3294 |
3247 /* Pretend to take the address of the base, we'll take care of | 3295 /* Avoid creating pointer-offset constraints, so handle MEM_REF |
3248 adding the required subset of sub-fields below. */ | 3296 offsets directly. Pretend to take the address of the base, |
3249 get_constraint_for_1 (t, results, true, lhs_p); | 3297 we'll take care of adding the required subset of sub-fields below. */ |
3298 if (TREE_CODE (t) == MEM_REF | |
3299 && !integer_zerop (TREE_OPERAND (t, 0))) | |
3300 { | |
3301 poly_offset_int off = mem_ref_offset (t); | |
3302 off <<= LOG2_BITS_PER_UNIT; | |
3303 off += bitpos; | |
3304 poly_int64 off_hwi; | |
3305 if (off.to_shwi (&off_hwi)) | |
3306 bitpos = off_hwi; | |
3307 else | |
3308 { | |
3309 bitpos = 0; | |
3310 bitmaxsize = -1; | |
3311 } | |
3312 get_constraint_for_1 (TREE_OPERAND (t, 0), results, false, lhs_p); | |
3313 do_deref (results); | |
3314 } | |
3315 else | |
3316 get_constraint_for_1 (t, results, true, lhs_p); | |
3317 | |
3250 /* Strip off nothing_id. */ | 3318 /* Strip off nothing_id. */ |
3251 if (results->length () == 2) | 3319 if (results->length () == 2) |
3252 { | 3320 { |
3253 gcc_assert ((*results)[0].var == nothing_id); | 3321 gcc_assert ((*results)[0].var == nothing_id); |
3254 results->unordered_remove (0); | 3322 results->unordered_remove (0); |
3846 | 3914 |
3847 heapvar = build_fake_var_decl (ptr_type_node); | 3915 heapvar = build_fake_var_decl (ptr_type_node); |
3848 DECL_EXTERNAL (heapvar) = 1; | 3916 DECL_EXTERNAL (heapvar) = 1; |
3849 | 3917 |
3850 vi = new_var_info (heapvar, name, add_id); | 3918 vi = new_var_info (heapvar, name, add_id); |
3851 vi->is_artificial_var = true; | |
3852 vi->is_heap_var = true; | 3919 vi->is_heap_var = true; |
3853 vi->is_unknown_size_var = true; | 3920 vi->is_unknown_size_var = true; |
3854 vi->offset = 0; | 3921 vi->offset = 0; |
3855 vi->fullsize = ~0; | 3922 vi->fullsize = ~0; |
3856 vi->size = ~0; | 3923 vi->size = ~0; |
4399 ac.var = integer_id; | 4466 ac.var = integer_id; |
4400 } | 4467 } |
4401 ac.offset = 0; | 4468 ac.offset = 0; |
4402 FOR_EACH_VEC_ELT (lhsc, i, lhsp) | 4469 FOR_EACH_VEC_ELT (lhsc, i, lhsp) |
4403 process_constraint (new_constraint (*lhsp, ac)); | 4470 process_constraint (new_constraint (*lhsp, ac)); |
4471 return true; | |
4472 } | |
4473 case BUILT_IN_STACK_SAVE: | |
4474 case BUILT_IN_STACK_RESTORE: | |
4475 /* Nothing interesting happens. */ | |
4476 return true; | |
4477 case BUILT_IN_ALLOCA: | |
4478 case BUILT_IN_ALLOCA_WITH_ALIGN: | |
4479 case BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX: | |
4480 { | |
4481 tree ptr = gimple_call_lhs (t); | |
4482 if (ptr == NULL_TREE) | |
4483 return true; | |
4484 get_constraint_for (ptr, &lhsc); | |
4485 varinfo_t vi = make_heapvar ("HEAP", true); | |
4486 /* Alloca storage is never global. To exempt it from escaped | |
4487 handling make it a non-heap var. */ | |
4488 DECL_EXTERNAL (vi->decl) = 0; | |
4489 vi->is_global_var = 0; | |
4490 vi->is_heap_var = 0; | |
4491 struct constraint_expr tmpc; | |
4492 tmpc.var = vi->id; | |
4493 tmpc.offset = 0; | |
4494 tmpc.type = ADDRESSOF; | |
4495 rhsc.safe_push (tmpc); | |
4496 process_all_all_constraints (lhsc, rhsc); | |
4404 return true; | 4497 return true; |
4405 } | 4498 } |
4406 case BUILT_IN_POSIX_MEMALIGN: | 4499 case BUILT_IN_POSIX_MEMALIGN: |
4407 { | 4500 { |
4408 tree ptrptr = gimple_call_arg (t, 0); | 4501 tree ptrptr = gimple_call_arg (t, 0); |
4695 /* __builtin_GOMP_parallel (fn, data, num_threads, flags). */ | 4788 /* __builtin_GOMP_parallel (fn, data, num_threads, flags). */ |
4696 fnpos = 0; | 4789 fnpos = 0; |
4697 argpos = 1; | 4790 argpos = 1; |
4698 break; | 4791 break; |
4699 case BUILT_IN_GOACC_PARALLEL: | 4792 case BUILT_IN_GOACC_PARALLEL: |
4700 /* __builtin_GOACC_parallel (device, fn, mapnum, hostaddrs, | 4793 /* __builtin_GOACC_parallel (flags_m, fn, mapnum, hostaddrs, |
4701 sizes, kinds, ...). */ | 4794 sizes, kinds, ...). */ |
4702 fnpos = 1; | 4795 fnpos = 1; |
4703 argpos = 3; | 4796 argpos = 3; |
4704 break; | 4797 break; |
4705 default: | 4798 default: |
4892 get_constraint_for (lhsop, &lhsc); | 4985 get_constraint_for (lhsop, &lhsc); |
4893 | 4986 |
4894 if (code == POINTER_PLUS_EXPR) | 4987 if (code == POINTER_PLUS_EXPR) |
4895 get_constraint_for_ptr_offset (gimple_assign_rhs1 (t), | 4988 get_constraint_for_ptr_offset (gimple_assign_rhs1 (t), |
4896 gimple_assign_rhs2 (t), &rhsc); | 4989 gimple_assign_rhs2 (t), &rhsc); |
4990 else if (code == POINTER_DIFF_EXPR) | |
4991 /* The result is not a pointer (part). */ | |
4992 ; | |
4897 else if (code == BIT_AND_EXPR | 4993 else if (code == BIT_AND_EXPR |
4898 && TREE_CODE (gimple_assign_rhs2 (t)) == INTEGER_CST) | 4994 && TREE_CODE (gimple_assign_rhs2 (t)) == INTEGER_CST) |
4899 { | 4995 { |
4900 /* Aligning a pointer via a BIT_AND_EXPR is offsetting | 4996 /* Aligning a pointer via a BIT_AND_EXPR is offsetting |
4901 the pointer. Handle it by offsetting it by UNKNOWN. */ | 4997 the pointer. Handle it by offsetting it by UNKNOWN. */ |
4902 get_constraint_for_ptr_offset (gimple_assign_rhs1 (t), | 4998 get_constraint_for_ptr_offset (gimple_assign_rhs1 (t), |
4903 NULL_TREE, &rhsc); | 4999 NULL_TREE, &rhsc); |
4904 } | 5000 } |
4905 else if ((CONVERT_EXPR_CODE_P (code) | 5001 else if (code == TRUNC_DIV_EXPR |
4906 && !(POINTER_TYPE_P (gimple_expr_type (t)) | 5002 || code == CEIL_DIV_EXPR |
4907 && !POINTER_TYPE_P (TREE_TYPE (rhsop)))) | 5003 || code == FLOOR_DIV_EXPR |
5004 || code == ROUND_DIV_EXPR | |
5005 || code == EXACT_DIV_EXPR | |
5006 || code == TRUNC_MOD_EXPR | |
5007 || code == CEIL_MOD_EXPR | |
5008 || code == FLOOR_MOD_EXPR | |
5009 || code == ROUND_MOD_EXPR) | |
5010 /* Division and modulo transfer the pointer from the LHS. */ | |
5011 get_constraint_for_ptr_offset (gimple_assign_rhs1 (t), | |
5012 NULL_TREE, &rhsc); | |
5013 else if (CONVERT_EXPR_CODE_P (code) | |
4908 || gimple_assign_single_p (t)) | 5014 || gimple_assign_single_p (t)) |
5015 /* See through conversions, single RHS are handled by | |
5016 get_constraint_for_rhs. */ | |
4909 get_constraint_for_rhs (rhsop, &rhsc); | 5017 get_constraint_for_rhs (rhsop, &rhsc); |
4910 else if (code == COND_EXPR) | 5018 else if (code == COND_EXPR) |
4911 { | 5019 { |
4912 /* The result is a merge of both COND_EXPR arms. */ | 5020 /* The result is a merge of both COND_EXPR arms. */ |
4913 auto_vec<ce_s, 2> tmp; | 5021 auto_vec<ce_s, 2> tmp; |
4922 /* Truth value results are not pointer (parts). Or at least | 5030 /* Truth value results are not pointer (parts). Or at least |
4923 very unreasonable obfuscation of a part. */ | 5031 very unreasonable obfuscation of a part. */ |
4924 ; | 5032 ; |
4925 else | 5033 else |
4926 { | 5034 { |
4927 /* All other operations are merges. */ | 5035 /* All other operations are possibly offsetting merges. */ |
4928 auto_vec<ce_s, 4> tmp; | 5036 auto_vec<ce_s, 4> tmp; |
4929 struct constraint_expr *rhsp; | 5037 struct constraint_expr *rhsp; |
4930 unsigned i, j; | 5038 unsigned i, j; |
4931 get_constraint_for_rhs (gimple_assign_rhs1 (t), &rhsc); | 5039 get_constraint_for_ptr_offset (gimple_assign_rhs1 (t), |
5040 NULL_TREE, &rhsc); | |
4932 for (i = 2; i < gimple_num_ops (t); ++i) | 5041 for (i = 2; i < gimple_num_ops (t); ++i) |
4933 { | 5042 { |
4934 get_constraint_for_rhs (gimple_op (t, i), &tmp); | 5043 get_constraint_for_ptr_offset (gimple_op (t, i), |
5044 NULL_TREE, &tmp); | |
4935 FOR_EACH_VEC_ELT (tmp, j, rhsp) | 5045 FOR_EACH_VEC_ELT (tmp, j, rhsp) |
4936 rhsc.safe_push (*rhsp); | 5046 rhsc.safe_push (*rhsp); |
4937 tmp.truncate (0); | 5047 tmp.truncate (0); |
4938 } | 5048 } |
4939 } | 5049 } |
4954 && gimple_return_retval (as_a <greturn *> (t)) != NULL_TREE) | 5064 && gimple_return_retval (as_a <greturn *> (t)) != NULL_TREE) |
4955 { | 5065 { |
4956 greturn *return_stmt = as_a <greturn *> (t); | 5066 greturn *return_stmt = as_a <greturn *> (t); |
4957 fi = NULL; | 5067 fi = NULL; |
4958 if (!in_ipa_mode | 5068 if (!in_ipa_mode |
4959 || !(fi = get_vi_for_tree (fn->decl))) | 5069 && SSA_VAR_P (gimple_return_retval (return_stmt))) |
5070 { | |
5071 /* We handle simple returns by post-processing the solutions. */ | |
5072 ; | |
5073 } | |
5074 if (!(fi = get_vi_for_tree (fn->decl))) | |
4960 make_escape_constraint (gimple_return_retval (return_stmt)); | 5075 make_escape_constraint (gimple_return_retval (return_stmt)); |
4961 else if (in_ipa_mode) | 5076 else if (in_ipa_mode) |
4962 { | 5077 { |
4963 struct constraint_expr lhs ; | 5078 struct constraint_expr lhs ; |
4964 struct constraint_expr *rhsp; | 5079 struct constraint_expr *rhsp; |
5253 /* __builtin_GOMP_parallel (fn, data, num_threads, flags). */ | 5368 /* __builtin_GOMP_parallel (fn, data, num_threads, flags). */ |
5254 fnpos = 0; | 5369 fnpos = 0; |
5255 argpos = 1; | 5370 argpos = 1; |
5256 break; | 5371 break; |
5257 case BUILT_IN_GOACC_PARALLEL: | 5372 case BUILT_IN_GOACC_PARALLEL: |
5258 /* __builtin_GOACC_parallel (device, fn, mapnum, hostaddrs, | 5373 /* __builtin_GOACC_parallel (flags_m, fn, mapnum, hostaddrs, |
5259 sizes, kinds, ...). */ | 5374 sizes, kinds, ...). */ |
5260 fnpos = 1; | 5375 fnpos = 1; |
5261 argpos = 3; | 5376 argpos = 3; |
5262 implicit_use_args[num_implicit_use_args++] = 4; | 5377 implicit_use_args[num_implicit_use_args++] = 4; |
5263 implicit_use_args[num_implicit_use_args++] = 5; | 5378 implicit_use_args[num_implicit_use_args++] = 5; |
5580 | 5695 |
5581 if (TREE_CODE (type) != RECORD_TYPE) | 5696 if (TREE_CODE (type) != RECORD_TYPE) |
5582 return false; | 5697 return false; |
5583 | 5698 |
5584 /* If the vector of fields is growing too big, bail out early. | 5699 /* If the vector of fields is growing too big, bail out early. |
5585 Callers check for vec::length <= MAX_FIELDS_FOR_FIELD_SENSITIVE, make | 5700 Callers check for vec::length <= param_max_fields_for_field_sensitive, make |
5586 sure this fails. */ | 5701 sure this fails. */ |
5587 if (fieldstack->length () > MAX_FIELDS_FOR_FIELD_SENSITIVE) | 5702 if (fieldstack->length () > (unsigned)param_max_fields_for_field_sensitive) |
5588 return false; | 5703 return false; |
5589 | 5704 |
5590 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) | 5705 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) |
5591 if (TREE_CODE (field) == FIELD_DECL) | 5706 if (TREE_CODE (field) == FIELD_DECL) |
5592 { | 5707 { |
5902 && argvi->may_have_pointers) | 6017 && argvi->may_have_pointers) |
5903 make_constraint_from (argvi, nonlocal_id); | 6018 make_constraint_from (argvi, nonlocal_id); |
5904 | 6019 |
5905 gcc_assert (prev_vi->offset < argvi->offset); | 6020 gcc_assert (prev_vi->offset < argvi->offset); |
5906 prev_vi->next = argvi->id; | 6021 prev_vi->next = argvi->id; |
5907 prev_vi = argvi; | |
5908 } | 6022 } |
5909 | 6023 |
5910 return vi; | 6024 return vi; |
5911 } | 6025 } |
5912 | 6026 |
6004 } | 6118 } |
6005 | 6119 |
6006 /* If we didn't end up collecting sub-variables create a full | 6120 /* If we didn't end up collecting sub-variables create a full |
6007 variable for the decl. */ | 6121 variable for the decl. */ |
6008 if (fieldstack.length () == 0 | 6122 if (fieldstack.length () == 0 |
6009 || fieldstack.length () > MAX_FIELDS_FOR_FIELD_SENSITIVE) | 6123 || fieldstack.length () > (unsigned)param_max_fields_for_field_sensitive) |
6010 { | 6124 { |
6011 vi = new_var_info (decl, name, add_id); | 6125 vi = new_var_info (decl, name, add_id); |
6012 vi->offset = 0; | 6126 vi->offset = 0; |
6013 vi->may_have_pointers = true; | 6127 vi->may_have_pointers = true; |
6014 vi->fullsize = tree_to_uhwi (declsize); | 6128 vi->fullsize = tree_to_uhwi (declsize); |
6400 | 6514 |
6401 EXECUTE_IF_SET_IN_BITMAP (from, 0, i, bi) | 6515 EXECUTE_IF_SET_IN_BITMAP (from, 0, i, bi) |
6402 { | 6516 { |
6403 varinfo_t vi = get_varinfo (i); | 6517 varinfo_t vi = get_varinfo (i); |
6404 | 6518 |
6405 /* The only artificial variables that are allowed in a may-alias | 6519 if (vi->is_artificial_var) |
6406 set are heap variables. */ | |
6407 if (vi->is_artificial_var && !vi->is_heap_var) | |
6408 continue; | 6520 continue; |
6409 | 6521 |
6410 if (everything_escaped | 6522 if (everything_escaped |
6411 || (escaped_vi->solution | 6523 || (escaped_vi->solution |
6412 && bitmap_bit_p (escaped_vi->solution, i))) | 6524 && bitmap_bit_p (escaped_vi->solution, i))) |
6413 { | 6525 { |
6414 pt->vars_contains_escaped = true; | 6526 pt->vars_contains_escaped = true; |
6415 pt->vars_contains_escaped_heap = vi->is_heap_var; | 6527 pt->vars_contains_escaped_heap |= vi->is_heap_var; |
6416 } | 6528 } |
6417 | 6529 |
6418 if (vi->is_restrict_var) | 6530 if (vi->is_restrict_var) |
6419 pt->vars_contains_restrict = true; | 6531 pt->vars_contains_restrict = true; |
6420 | 6532 |
6450 for pointer comparison simplification. */ | 6562 for pointer comparison simplification. */ |
6451 if (VAR_P (vi->decl) | 6563 if (VAR_P (vi->decl) |
6452 && (TREE_STATIC (vi->decl) || DECL_EXTERNAL (vi->decl)) | 6564 && (TREE_STATIC (vi->decl) || DECL_EXTERNAL (vi->decl)) |
6453 && ! decl_binds_to_current_def_p (vi->decl)) | 6565 && ! decl_binds_to_current_def_p (vi->decl)) |
6454 pt->vars_contains_interposable = true; | 6566 pt->vars_contains_interposable = true; |
6567 | |
6568 /* If this is a local variable we can have overlapping lifetime | |
6569 of different function invocations through recursion duplicate | |
6570 it with its shadow variable. */ | |
6571 if (in_ipa_mode | |
6572 && vi->shadow_var_uid != 0) | |
6573 { | |
6574 bitmap_set_bit (into, vi->shadow_var_uid); | |
6575 pt->vars_contains_nonlocal = true; | |
6576 } | |
6455 } | 6577 } |
6456 | 6578 |
6457 else if (TREE_CODE (vi->decl) == FUNCTION_DECL | 6579 else if (TREE_CODE (vi->decl) == FUNCTION_DECL |
6458 || TREE_CODE (vi->decl) == LABEL_DECL) | 6580 || TREE_CODE (vi->decl) == LABEL_DECL) |
6459 { | 6581 { |
6512 if (bitmap_bit_p (evi->solution, nonlocal_id)) | 6634 if (bitmap_bit_p (evi->solution, nonlocal_id)) |
6513 pt->nonlocal = 1; | 6635 pt->nonlocal = 1; |
6514 } | 6636 } |
6515 else if (vi->id == nonlocal_id) | 6637 else if (vi->id == nonlocal_id) |
6516 pt->nonlocal = 1; | 6638 pt->nonlocal = 1; |
6517 else if (vi->is_heap_var) | |
6518 /* We represent heapvars in the points-to set properly. */ | |
6519 ; | |
6520 else if (vi->id == string_id) | 6639 else if (vi->id == string_id) |
6521 /* Nobody cares - STRING_CSTs are read-only entities. */ | 6640 /* Nobody cares - STRING_CSTs are read-only entities. */ |
6522 ; | 6641 ; |
6523 else if (vi->id == anything_id | 6642 else if (vi->id == anything_id |
6524 || vi->id == integer_id) | 6643 || vi->id == integer_id) |
6686 } | 6805 } |
6687 | 6806 |
6688 /* Return true if the points-to solution *PT is empty. */ | 6807 /* Return true if the points-to solution *PT is empty. */ |
6689 | 6808 |
6690 bool | 6809 bool |
6691 pt_solution_empty_p (struct pt_solution *pt) | 6810 pt_solution_empty_p (const pt_solution *pt) |
6692 { | 6811 { |
6693 if (pt->anything | 6812 if (pt->anything |
6694 || pt->nonlocal) | 6813 || pt->nonlocal) |
6695 return false; | 6814 return false; |
6696 | 6815 |
7064 /* Initialize things necessary to perform PTA */ | 7183 /* Initialize things necessary to perform PTA */ |
7065 | 7184 |
7066 static void | 7185 static void |
7067 init_alias_vars (void) | 7186 init_alias_vars (void) |
7068 { | 7187 { |
7069 use_field_sensitive = (MAX_FIELDS_FOR_FIELD_SENSITIVE > 1); | 7188 use_field_sensitive = (param_max_fields_for_field_sensitive > 1); |
7070 | 7189 |
7071 bitmap_obstack_initialize (&pta_obstack); | 7190 bitmap_obstack_initialize (&pta_obstack); |
7072 bitmap_obstack_initialize (&oldpta_obstack); | 7191 bitmap_obstack_initialize (&oldpta_obstack); |
7073 bitmap_obstack_initialize (&predbitmap_obstack); | 7192 bitmap_obstack_initialize (&predbitmap_obstack); |
7074 | 7193 |
7126 /* Solve the constraint set. */ | 7245 /* Solve the constraint set. */ |
7127 | 7246 |
7128 static void | 7247 static void |
7129 solve_constraints (void) | 7248 solve_constraints (void) |
7130 { | 7249 { |
7131 struct scc_info *si; | 7250 class scc_info *si; |
7132 | 7251 |
7133 /* Sort varinfos so that ones that cannot be pointed to are last. | 7252 /* Sort varinfos so that ones that cannot be pointed to are last. |
7134 This makes bitmaps more efficient. */ | 7253 This makes bitmaps more efficient. */ |
7135 unsigned int *map = XNEWVEC (unsigned int, varmap.length ()); | 7254 unsigned int *map = XNEWVEC (unsigned int, varmap.length ()); |
7136 for (unsigned i = 0; i < integer_id + 1; ++i) | 7255 for (unsigned i = 0; i < integer_id + 1; ++i) |
7222 fprintf (dump_file, "\n\n// The constraint graph after solve-graph " | 7341 fprintf (dump_file, "\n\n// The constraint graph after solve-graph " |
7223 "in dot format:\n"); | 7342 "in dot format:\n"); |
7224 dump_constraint_graph (dump_file); | 7343 dump_constraint_graph (dump_file); |
7225 fprintf (dump_file, "\n\n"); | 7344 fprintf (dump_file, "\n\n"); |
7226 } | 7345 } |
7346 } | |
7347 | |
7348 /* Create points-to sets for the current function. See the comments | |
7349 at the start of the file for an algorithmic overview. */ | |
7350 | |
7351 static void | |
7352 compute_points_to_sets (void) | |
7353 { | |
7354 basic_block bb; | |
7355 varinfo_t vi; | |
7356 | |
7357 timevar_push (TV_TREE_PTA); | |
7358 | |
7359 init_alias_vars (); | |
7360 | |
7361 intra_create_variable_infos (cfun); | |
7362 | |
7363 /* Now walk all statements and build the constraint set. */ | |
7364 FOR_EACH_BB_FN (bb, cfun) | |
7365 { | |
7366 for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi); | |
7367 gsi_next (&gsi)) | |
7368 { | |
7369 gphi *phi = gsi.phi (); | |
7370 | |
7371 if (! virtual_operand_p (gimple_phi_result (phi))) | |
7372 find_func_aliases (cfun, phi); | |
7373 } | |
7374 | |
7375 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); | |
7376 gsi_next (&gsi)) | |
7377 { | |
7378 gimple *stmt = gsi_stmt (gsi); | |
7379 | |
7380 find_func_aliases (cfun, stmt); | |
7381 } | |
7382 } | |
7383 | |
7384 if (dump_file) | |
7385 { | |
7386 fprintf (dump_file, "Points-to analysis\n\nConstraints:\n\n"); | |
7387 dump_constraints (dump_file, 0); | |
7388 } | |
7389 | |
7390 /* From the constraints compute the points-to sets. */ | |
7391 solve_constraints (); | |
7392 | |
7393 /* Post-process solutions for escapes through returns. */ | |
7394 edge_iterator ei; | |
7395 edge e; | |
7396 FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) | |
7397 if (greturn *ret = safe_dyn_cast <greturn *> (last_stmt (e->src))) | |
7398 { | |
7399 tree val = gimple_return_retval (ret); | |
7400 /* ??? Easy to handle simple indirections with some work. | |
7401 Arbitrary references like foo.bar.baz are more difficult | |
7402 (but conservatively easy enough with just looking at the base). | |
7403 Mind to fixup find_func_aliases as well. */ | |
7404 if (!val || !SSA_VAR_P (val)) | |
7405 continue; | |
7406 /* returns happen last in non-IPA so they only influence | |
7407 the ESCAPED solution and we can filter local variables. */ | |
7408 varinfo_t escaped_vi = get_varinfo (find (escaped_id)); | |
7409 varinfo_t vi = lookup_vi_for_tree (val); | |
7410 bitmap delta = BITMAP_ALLOC (&pta_obstack); | |
7411 bitmap_iterator bi; | |
7412 unsigned i; | |
7413 for (; vi; vi = vi_next (vi)) | |
7414 { | |
7415 varinfo_t part_vi = get_varinfo (find (vi->id)); | |
7416 EXECUTE_IF_AND_COMPL_IN_BITMAP (part_vi->solution, | |
7417 escaped_vi->solution, 0, i, bi) | |
7418 { | |
7419 varinfo_t pointed_to_vi = get_varinfo (i); | |
7420 if (pointed_to_vi->is_global_var | |
7421 /* We delay marking of heap memory as global. */ | |
7422 || pointed_to_vi->is_heap_var) | |
7423 bitmap_set_bit (delta, i); | |
7424 } | |
7425 } | |
7426 | |
7427 /* Now compute the transitive closure. */ | |
7428 bitmap_ior_into (escaped_vi->solution, delta); | |
7429 bitmap new_delta = BITMAP_ALLOC (&pta_obstack); | |
7430 while (!bitmap_empty_p (delta)) | |
7431 { | |
7432 EXECUTE_IF_SET_IN_BITMAP (delta, 0, i, bi) | |
7433 { | |
7434 varinfo_t pointed_to_vi = get_varinfo (i); | |
7435 pointed_to_vi = get_varinfo (find (pointed_to_vi->id)); | |
7436 unsigned j; | |
7437 bitmap_iterator bi2; | |
7438 EXECUTE_IF_AND_COMPL_IN_BITMAP (pointed_to_vi->solution, | |
7439 escaped_vi->solution, | |
7440 0, j, bi2) | |
7441 { | |
7442 varinfo_t pointed_to_vi2 = get_varinfo (j); | |
7443 if (pointed_to_vi2->is_global_var | |
7444 /* We delay marking of heap memory as global. */ | |
7445 || pointed_to_vi2->is_heap_var) | |
7446 bitmap_set_bit (new_delta, j); | |
7447 } | |
7448 } | |
7449 bitmap_ior_into (escaped_vi->solution, new_delta); | |
7450 bitmap_clear (delta); | |
7451 std::swap (delta, new_delta); | |
7452 } | |
7453 BITMAP_FREE (delta); | |
7454 BITMAP_FREE (new_delta); | |
7455 } | |
7227 | 7456 |
7228 if (dump_file) | 7457 if (dump_file) |
7229 dump_sa_points_to_info (dump_file); | 7458 dump_sa_points_to_info (dump_file); |
7230 } | |
7231 | |
7232 /* Create points-to sets for the current function. See the comments | |
7233 at the start of the file for an algorithmic overview. */ | |
7234 | |
7235 static void | |
7236 compute_points_to_sets (void) | |
7237 { | |
7238 basic_block bb; | |
7239 varinfo_t vi; | |
7240 | |
7241 timevar_push (TV_TREE_PTA); | |
7242 | |
7243 init_alias_vars (); | |
7244 | |
7245 intra_create_variable_infos (cfun); | |
7246 | |
7247 /* Now walk all statements and build the constraint set. */ | |
7248 FOR_EACH_BB_FN (bb, cfun) | |
7249 { | |
7250 for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi); | |
7251 gsi_next (&gsi)) | |
7252 { | |
7253 gphi *phi = gsi.phi (); | |
7254 | |
7255 if (! virtual_operand_p (gimple_phi_result (phi))) | |
7256 find_func_aliases (cfun, phi); | |
7257 } | |
7258 | |
7259 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); | |
7260 gsi_next (&gsi)) | |
7261 { | |
7262 gimple *stmt = gsi_stmt (gsi); | |
7263 | |
7264 find_func_aliases (cfun, stmt); | |
7265 } | |
7266 } | |
7267 | |
7268 if (dump_file) | |
7269 { | |
7270 fprintf (dump_file, "Points-to analysis\n\nConstraints:\n\n"); | |
7271 dump_constraints (dump_file, 0); | |
7272 } | |
7273 | |
7274 /* From the constraints compute the points-to sets. */ | |
7275 solve_constraints (); | |
7276 | 7459 |
7277 /* Compute the points-to set for ESCAPED used for call-clobber analysis. */ | 7460 /* Compute the points-to set for ESCAPED used for call-clobber analysis. */ |
7278 cfun->gimple_df->escaped = find_what_var_points_to (cfun->decl, | 7461 cfun->gimple_df->escaped = find_what_var_points_to (cfun->decl, |
7279 get_varinfo (escaped_id)); | 7462 get_varinfo (escaped_id)); |
7280 | 7463 |
7493 into a function with restrict parameters. This usually means we | 7676 into a function with restrict parameters. This usually means we |
7494 prefer to be precise in innermost loops. */ | 7677 prefer to be precise in innermost loops. */ |
7495 if (MR_DEPENDENCE_CLIQUE (base) == 0) | 7678 if (MR_DEPENDENCE_CLIQUE (base) == 0) |
7496 { | 7679 { |
7497 if (clique == 0) | 7680 if (clique == 0) |
7498 clique = ++cfun->last_clique; | 7681 { |
7682 if (cfun->last_clique == 0) | |
7683 cfun->last_clique = 1; | |
7684 clique = 1; | |
7685 } | |
7499 if (restrict_var->ruid == 0) | 7686 if (restrict_var->ruid == 0) |
7500 restrict_var->ruid = ++last_ruid; | 7687 restrict_var->ruid = ++last_ruid; |
7501 MR_DEPENDENCE_CLIQUE (base) = clique; | 7688 MR_DEPENDENCE_CLIQUE (base) = clique; |
7502 MR_DEPENDENCE_BASE (base) = restrict_var->ruid; | 7689 MR_DEPENDENCE_BASE (base) = restrict_var->ruid; |
7503 return true; | 7690 return true; |
7504 } | 7691 } |
7505 } | 7692 } |
7506 return false; | 7693 return false; |
7507 } | 7694 } |
7508 | 7695 |
7696 /* Clear dependence info for the clique DATA. */ | |
7697 | |
7698 static bool | |
7699 clear_dependence_clique (gimple *, tree base, tree, void *data) | |
7700 { | |
7701 unsigned short clique = (uintptr_t)data; | |
7702 if ((TREE_CODE (base) == MEM_REF | |
7703 || TREE_CODE (base) == TARGET_MEM_REF) | |
7704 && MR_DEPENDENCE_CLIQUE (base) == clique) | |
7705 { | |
7706 MR_DEPENDENCE_CLIQUE (base) = 0; | |
7707 MR_DEPENDENCE_BASE (base) = 0; | |
7708 } | |
7709 | |
7710 return false; | |
7711 } | |
7712 | |
7509 /* Compute the set of independend memory references based on restrict | 7713 /* Compute the set of independend memory references based on restrict |
7510 tags and their conservative propagation to the points-to sets. */ | 7714 tags and their conservative propagation to the points-to sets. */ |
7511 | 7715 |
7512 static void | 7716 static void |
7513 compute_dependence_clique (void) | 7717 compute_dependence_clique (void) |
7514 { | 7718 { |
7719 /* First clear the special "local" clique. */ | |
7720 basic_block bb; | |
7721 if (cfun->last_clique != 0) | |
7722 FOR_EACH_BB_FN (bb, cfun) | |
7723 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); | |
7724 !gsi_end_p (gsi); gsi_next (&gsi)) | |
7725 { | |
7726 gimple *stmt = gsi_stmt (gsi); | |
7727 walk_stmt_load_store_ops (stmt, (void *)(uintptr_t) 1, | |
7728 clear_dependence_clique, | |
7729 clear_dependence_clique); | |
7730 } | |
7731 | |
7515 unsigned short clique = 0; | 7732 unsigned short clique = 0; |
7516 unsigned short last_ruid = 0; | 7733 unsigned short last_ruid = 0; |
7517 bitmap rvars = BITMAP_ALLOC (NULL); | 7734 bitmap rvars = BITMAP_ALLOC (NULL); |
7518 bool escaped_p = false; | 7735 bool escaped_p = false; |
7519 for (unsigned i = 0; i < num_ssa_names; ++i) | 7736 for (unsigned i = 0; i < num_ssa_names; ++i) |
7536 unsigned j; | 7753 unsigned j; |
7537 varinfo_t restrict_var = NULL; | 7754 varinfo_t restrict_var = NULL; |
7538 EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, j, bi) | 7755 EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, j, bi) |
7539 { | 7756 { |
7540 varinfo_t oi = get_varinfo (j); | 7757 varinfo_t oi = get_varinfo (j); |
7758 if (oi->head != j) | |
7759 oi = get_varinfo (oi->head); | |
7541 if (oi->is_restrict_var) | 7760 if (oi->is_restrict_var) |
7542 { | 7761 { |
7543 if (restrict_var) | 7762 if (restrict_var |
7763 && restrict_var != oi) | |
7544 { | 7764 { |
7545 if (dump_file && (dump_flags & TDF_DETAILS)) | 7765 if (dump_file && (dump_flags & TDF_DETAILS)) |
7546 { | 7766 { |
7547 fprintf (dump_file, "found restrict pointed-to " | 7767 fprintf (dump_file, "found restrict pointed-to " |
7548 "for "); | 7768 "for "); |
7577 used |= walk_stmt_load_store_ops (use_stmt, &data, | 7797 used |= walk_stmt_load_store_ops (use_stmt, &data, |
7578 maybe_set_dependence_info, | 7798 maybe_set_dependence_info, |
7579 maybe_set_dependence_info); | 7799 maybe_set_dependence_info); |
7580 if (used) | 7800 if (used) |
7581 { | 7801 { |
7582 bitmap_set_bit (rvars, restrict_var->id); | 7802 /* Add all subvars to the set of restrict pointed-to set. */ |
7803 for (unsigned sv = restrict_var->head; sv != 0; | |
7804 sv = get_varinfo (sv)->next) | |
7805 bitmap_set_bit (rvars, sv); | |
7583 varinfo_t escaped = get_varinfo (find (escaped_id)); | 7806 varinfo_t escaped = get_varinfo (find (escaped_id)); |
7584 if (bitmap_bit_p (escaped->solution, restrict_var->id)) | 7807 if (bitmap_bit_p (escaped->solution, restrict_var->id)) |
7585 escaped_p = true; | 7808 escaped_p = true; |
7586 } | 7809 } |
7587 } | 7810 } |
7740 static bool | 7963 static bool |
7741 associate_varinfo_to_alias (struct cgraph_node *node, void *data) | 7964 associate_varinfo_to_alias (struct cgraph_node *node, void *data) |
7742 { | 7965 { |
7743 if ((node->alias | 7966 if ((node->alias |
7744 || (node->thunk.thunk_p | 7967 || (node->thunk.thunk_p |
7745 && ! node->global.inlined_to)) | 7968 && ! node->inlined_to)) |
7746 && node->analyzed | 7969 && node->analyzed |
7747 && !node->ifunc_resolver) | 7970 && !node->ifunc_resolver) |
7748 insert_vi_for_tree (node->decl, (varinfo_t)data); | 7971 insert_vi_for_tree (node->decl, (varinfo_t)data); |
7749 return false; | 7972 return false; |
7750 } | 7973 } |
7910 { | 8133 { |
7911 varinfo_t vi; | 8134 varinfo_t vi; |
7912 /* Nodes without a body are not interesting. Especially do not | 8135 /* Nodes without a body are not interesting. Especially do not |
7913 visit clones at this point for now - we get duplicate decls | 8136 visit clones at this point for now - we get duplicate decls |
7914 there for inline clones at least. */ | 8137 there for inline clones at least. */ |
7915 if (!node->has_gimple_body_p () || node->global.inlined_to) | 8138 if (!node->has_gimple_body_p () || node->inlined_to) |
7916 continue; | 8139 continue; |
7917 node->get_body (); | 8140 node->get_body (); |
7918 | 8141 |
7919 gcc_assert (!node->clone_of); | 8142 gcc_assert (!node->clone_of); |
7920 | 8143 |
7935 nonlocal_p); | 8158 nonlocal_p); |
7936 if (dump_file | 8159 if (dump_file |
7937 && from != constraints.length ()) | 8160 && from != constraints.length ()) |
7938 { | 8161 { |
7939 fprintf (dump_file, | 8162 fprintf (dump_file, |
7940 "Generating intial constraints for %s", node->name ()); | 8163 "Generating initial constraints for %s", |
8164 node->dump_name ()); | |
7941 if (DECL_ASSEMBLER_NAME_SET_P (node->decl)) | 8165 if (DECL_ASSEMBLER_NAME_SET_P (node->decl)) |
7942 fprintf (dump_file, " (%s)", | 8166 fprintf (dump_file, " (%s)", |
7943 IDENTIFIER_POINTER | 8167 IDENTIFIER_POINTER |
7944 (DECL_ASSEMBLER_NAME (node->decl))); | 8168 (DECL_ASSEMBLER_NAME (node->decl))); |
7945 fprintf (dump_file, "\n\n"); | 8169 fprintf (dump_file, "\n\n"); |
7992 continue; | 8216 continue; |
7993 | 8217 |
7994 if (dump_file) | 8218 if (dump_file) |
7995 { | 8219 { |
7996 fprintf (dump_file, | 8220 fprintf (dump_file, |
7997 "Generating constraints for %s", node->name ()); | 8221 "Generating constraints for %s", node->dump_name ()); |
7998 if (DECL_ASSEMBLER_NAME_SET_P (node->decl)) | 8222 if (DECL_ASSEMBLER_NAME_SET_P (node->decl)) |
7999 fprintf (dump_file, " (%s)", | 8223 fprintf (dump_file, " (%s)", |
8000 IDENTIFIER_POINTER | 8224 IDENTIFIER_POINTER |
8001 (DECL_ASSEMBLER_NAME (node->decl))); | 8225 (DECL_ASSEMBLER_NAME (node->decl))); |
8002 fprintf (dump_file, "\n"); | 8226 fprintf (dump_file, "\n"); |
8036 } | 8260 } |
8037 } | 8261 } |
8038 | 8262 |
8039 /* From the constraints compute the points-to sets. */ | 8263 /* From the constraints compute the points-to sets. */ |
8040 solve_constraints (); | 8264 solve_constraints (); |
8265 | |
8266 if (dump_file) | |
8267 dump_sa_points_to_info (dump_file); | |
8268 | |
8269 /* Now post-process solutions to handle locals from different | |
8270 runtime instantiations coming in through recursive invocations. */ | |
8271 unsigned shadow_var_cnt = 0; | |
8272 for (unsigned i = 1; i < varmap.length (); ++i) | |
8273 { | |
8274 varinfo_t fi = get_varinfo (i); | |
8275 if (fi->is_fn_info | |
8276 && fi->decl) | |
8277 /* Automatic variables pointed to by their containing functions | |
8278 parameters need this treatment. */ | |
8279 for (varinfo_t ai = first_vi_for_offset (fi, fi_parm_base); | |
8280 ai; ai = vi_next (ai)) | |
8281 { | |
8282 varinfo_t vi = get_varinfo (find (ai->id)); | |
8283 bitmap_iterator bi; | |
8284 unsigned j; | |
8285 EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, j, bi) | |
8286 { | |
8287 varinfo_t pt = get_varinfo (j); | |
8288 if (pt->shadow_var_uid == 0 | |
8289 && pt->decl | |
8290 && auto_var_in_fn_p (pt->decl, fi->decl)) | |
8291 { | |
8292 pt->shadow_var_uid = allocate_decl_uid (); | |
8293 shadow_var_cnt++; | |
8294 } | |
8295 } | |
8296 } | |
8297 /* As well as global variables which are another way of passing | |
8298 arguments to recursive invocations. */ | |
8299 else if (fi->is_global_var) | |
8300 { | |
8301 for (varinfo_t ai = fi; ai; ai = vi_next (ai)) | |
8302 { | |
8303 varinfo_t vi = get_varinfo (find (ai->id)); | |
8304 bitmap_iterator bi; | |
8305 unsigned j; | |
8306 EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, j, bi) | |
8307 { | |
8308 varinfo_t pt = get_varinfo (j); | |
8309 if (pt->shadow_var_uid == 0 | |
8310 && pt->decl | |
8311 && auto_var_p (pt->decl)) | |
8312 { | |
8313 pt->shadow_var_uid = allocate_decl_uid (); | |
8314 shadow_var_cnt++; | |
8315 } | |
8316 } | |
8317 } | |
8318 } | |
8319 } | |
8320 if (shadow_var_cnt && dump_file && (dump_flags & TDF_DETAILS)) | |
8321 fprintf (dump_file, "Allocated %u shadow variables for locals " | |
8322 "maybe leaking into recursive invocations of their containing " | |
8323 "functions\n", shadow_var_cnt); | |
8041 | 8324 |
8042 /* Compute the global points-to sets for ESCAPED. | 8325 /* Compute the global points-to sets for ESCAPED. |
8043 ??? Note that the computed escape set is not correct | 8326 ??? Note that the computed escape set is not correct |
8044 for the whole unit as we fail to consider graph edges to | 8327 for the whole unit as we fail to consider graph edges to |
8045 externally visible functions. */ | 8328 externally visible functions. */ |