1 1.1 mrg /* Tree based points-to analysis 2 1.1 mrg Copyright (C) 2005-2022 Free Software Foundation, Inc. 3 1.1 mrg Contributed by Daniel Berlin <dberlin (at) dberlin.org> 4 1.1 mrg 5 1.1 mrg This file is part of GCC. 6 1.1 mrg 7 1.1 mrg GCC is free software; you can redistribute it and/or modify 8 1.1 mrg under the terms of the GNU General Public License as published by 9 1.1 mrg the Free Software Foundation; either version 3 of the License, or 10 1.1 mrg (at your option) any later version. 11 1.1 mrg 12 1.1 mrg GCC is distributed in the hope that it will be useful, 13 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 mrg GNU General Public License for more details. 16 1.1 mrg 17 1.1 mrg You should have received a copy of the GNU General Public License 18 1.1 mrg along with GCC; see the file COPYING3. If not see 19 1.1 mrg <http://www.gnu.org/licenses/>. */ 20 1.1 mrg 21 1.1 mrg #include "config.h" 22 1.1 mrg #include "system.h" 23 1.1 mrg #include "coretypes.h" 24 1.1 mrg #include "backend.h" 25 1.1 mrg #include "rtl.h" 26 1.1 mrg #include "tree.h" 27 1.1 mrg #include "gimple.h" 28 1.1 mrg #include "alloc-pool.h" 29 1.1 mrg #include "tree-pass.h" 30 1.1 mrg #include "ssa.h" 31 1.1 mrg #include "cgraph.h" 32 1.1 mrg #include "tree-pretty-print.h" 33 1.1 mrg #include "diagnostic-core.h" 34 1.1 mrg #include "fold-const.h" 35 1.1 mrg #include "stor-layout.h" 36 1.1 mrg #include "stmt.h" 37 1.1 mrg #include "gimple-iterator.h" 38 1.1 mrg #include "tree-into-ssa.h" 39 1.1 mrg #include "tree-dfa.h" 40 1.1 mrg #include "gimple-walk.h" 41 1.1 mrg #include "varasm.h" 42 1.1 mrg #include "stringpool.h" 43 1.1 mrg #include "attribs.h" 44 1.1 mrg #include "tree-ssa.h" 45 1.1 mrg #include "tree-cfg.h" 46 1.1 mrg #include "gimple-range.h" 47 1.1 mrg #include "ipa-modref-tree.h" 48 1.1 mrg #include "ipa-modref.h" 49 1.1 mrg #include "attr-fnspec.h" 50 1.1 mrg 51 1.1 mrg /* The idea behind this analyzer is to generate set constraints from the 52 1.1 mrg program, then solve the resulting constraints in order to generate the 53 1.1 mrg points-to sets. 54 1.1 mrg 55 1.1 mrg Set constraints are a way of modeling program analysis problems that 56 1.1 mrg involve sets. They consist of an inclusion constraint language, 57 1.1 mrg describing the variables (each variable is a set) and operations that 58 1.1 mrg are involved on the variables, and a set of rules that derive facts 59 1.1 mrg from these operations. To solve a system of set constraints, you derive 60 1.1 mrg all possible facts under the rules, which gives you the correct sets 61 1.1 mrg as a consequence. 62 1.1 mrg 63 1.1 mrg See "Efficient Field-sensitive pointer analysis for C" by "David 64 1.1 mrg J. Pearce and Paul H. J. Kelly and Chris Hankin", at 65 1.1 mrg http://citeseer.ist.psu.edu/pearce04efficient.html 66 1.1 mrg 67 1.1 mrg Also see "Ultra-fast Aliasing Analysis using CLA: A Million Lines 68 1.1 mrg of C Code in a Second" by "Nevin Heintze and Olivier Tardieu" at 69 1.1 mrg http://citeseer.ist.psu.edu/heintze01ultrafast.html 70 1.1 mrg 71 1.1 mrg There are three types of real constraint expressions, DEREF, 72 1.1 mrg ADDRESSOF, and SCALAR. Each constraint expression consists 73 1.1 mrg of a constraint type, a variable, and an offset. 74 1.1 mrg 75 1.1 mrg SCALAR is a constraint expression type used to represent x, whether 76 1.1 mrg it appears on the LHS or the RHS of a statement. 77 1.1 mrg DEREF is a constraint expression type used to represent *x, whether 78 1.1 mrg it appears on the LHS or the RHS of a statement. 79 1.1 mrg ADDRESSOF is a constraint expression used to represent &x, whether 80 1.1 mrg it appears on the LHS or the RHS of a statement. 81 1.1 mrg 82 1.1 mrg Each pointer variable in the program is assigned an integer id, and 83 1.1 mrg each field of a structure variable is assigned an integer id as well. 84 1.1 mrg 85 1.1 mrg Structure variables are linked to their list of fields through a "next 86 1.1 mrg field" in each variable that points to the next field in offset 87 1.1 mrg order. 88 1.1 mrg Each variable for a structure field has 89 1.1 mrg 90 1.1 mrg 1. "size", that tells the size in bits of that field. 91 1.1 mrg 2. "fullsize", that tells the size in bits of the entire structure. 92 1.1 mrg 3. "offset", that tells the offset in bits from the beginning of the 93 1.1 mrg structure to this field. 94 1.1 mrg 95 1.1 mrg Thus, 96 1.1 mrg struct f 97 1.1 mrg { 98 1.1 mrg int a; 99 1.1 mrg int b; 100 1.1 mrg } foo; 101 1.1 mrg int *bar; 102 1.1 mrg 103 1.1 mrg looks like 104 1.1 mrg 105 1.1 mrg foo.a -> id 1, size 32, offset 0, fullsize 64, next foo.b 106 1.1 mrg foo.b -> id 2, size 32, offset 32, fullsize 64, next NULL 107 1.1 mrg bar -> id 3, size 32, offset 0, fullsize 32, next NULL 108 1.1 mrg 109 1.1 mrg 110 1.1 mrg In order to solve the system of set constraints, the following is 111 1.1 mrg done: 112 1.1 mrg 113 1.1 mrg 1. Each constraint variable x has a solution set associated with it, 114 1.1 mrg Sol(x). 115 1.1 mrg 116 1.1 mrg 2. Constraints are separated into direct, copy, and complex. 117 1.1 mrg Direct constraints are ADDRESSOF constraints that require no extra 118 1.1 mrg processing, such as P = &Q 119 1.1 mrg Copy constraints are those of the form P = Q. 120 1.1 mrg Complex constraints are all the constraints involving dereferences 121 1.1 mrg and offsets (including offsetted copies). 122 1.1 mrg 123 1.1 mrg 3. All direct constraints of the form P = &Q are processed, such 124 1.1 mrg that Q is added to Sol(P) 125 1.1 mrg 126 1.1 mrg 4. All complex constraints for a given constraint variable are stored in a 127 1.1 mrg linked list attached to that variable's node. 128 1.1 mrg 129 1.1 mrg 5. A directed graph is built out of the copy constraints. Each 130 1.1 mrg constraint variable is a node in the graph, and an edge from 131 1.1 mrg Q to P is added for each copy constraint of the form P = Q 132 1.1 mrg 133 1.1 mrg 6. The graph is then walked, and solution sets are 134 1.1 mrg propagated along the copy edges, such that an edge from Q to P 135 1.1 mrg causes Sol(P) <- Sol(P) union Sol(Q). 136 1.1 mrg 137 1.1 mrg 7. As we visit each node, all complex constraints associated with 138 1.1 mrg that node are processed by adding appropriate copy edges to the graph, or the 139 1.1 mrg appropriate variables to the solution set. 140 1.1 mrg 141 1.1 mrg 8. The process of walking the graph is iterated until no solution 142 1.1 mrg sets change. 143 1.1 mrg 144 1.1 mrg Prior to walking the graph in steps 6 and 7, We perform static 145 1.1 mrg cycle elimination on the constraint graph, as well 146 1.1 mrg as off-line variable substitution. 147 1.1 mrg 148 1.1 mrg TODO: Adding offsets to pointer-to-structures can be handled (IE not punted 149 1.1 mrg on and turned into anything), but isn't. You can just see what offset 150 1.1 mrg inside the pointed-to struct it's going to access. 151 1.1 mrg 152 1.1 mrg TODO: Constant bounded arrays can be handled as if they were structs of the 153 1.1 mrg same number of elements. 154 1.1 mrg 155 1.1 mrg TODO: Modeling heap and incoming pointers becomes much better if we 156 1.1 mrg add fields to them as we discover them, which we could do. 157 1.1 mrg 158 1.1 mrg TODO: We could handle unions, but to be honest, it's probably not 159 1.1 mrg worth the pain or slowdown. */ 160 1.1 mrg 161 1.1 mrg /* IPA-PTA optimizations possible. 162 1.1 mrg 163 1.1 mrg When the indirect function called is ANYTHING we can add disambiguation 164 1.1 mrg based on the function signatures (or simply the parameter count which 165 1.1 mrg is the varinfo size). We also do not need to consider functions that 166 1.1 mrg do not have their address taken. 167 1.1 mrg 168 1.1 mrg The is_global_var bit which marks escape points is overly conservative 169 1.1 mrg in IPA mode. Split it to is_escape_point and is_global_var - only 170 1.1 mrg externally visible globals are escape points in IPA mode. 171 1.1 mrg There is now is_ipa_escape_point but this is only used in a few 172 1.1 mrg selected places. 173 1.1 mrg 174 1.1 mrg The way we introduce DECL_PT_UID to avoid fixing up all points-to 175 1.1 mrg sets in the translation unit when we copy a DECL during inlining 176 1.1 mrg pessimizes precision. The advantage is that the DECL_PT_UID keeps 177 1.1 mrg compile-time and memory usage overhead low - the points-to sets 178 1.1 mrg do not grow or get unshared as they would during a fixup phase. 179 1.1 mrg An alternative solution is to delay IPA PTA until after all 180 1.1 mrg inlining transformations have been applied. 181 1.1 mrg 182 1.1 mrg The way we propagate clobber/use information isn't optimized. 183 1.1 mrg It should use a new complex constraint that properly filters 184 1.1 mrg out local variables of the callee (though that would make 185 1.1 mrg the sets invalid after inlining). OTOH we might as well 186 1.1 mrg admit defeat to WHOPR and simply do all the clobber/use analysis 187 1.1 mrg and propagation after PTA finished but before we threw away 188 1.1 mrg points-to information for memory variables. WHOPR and PTA 189 1.1 mrg do not play along well anyway - the whole constraint solving 190 1.1 mrg would need to be done in WPA phase and it will be very interesting 191 1.1 mrg to apply the results to local SSA names during LTRANS phase. 192 1.1 mrg 193 1.1 mrg We probably should compute a per-function unit-ESCAPE solution 194 1.1 mrg propagating it simply like the clobber / uses solutions. The 195 1.1 mrg solution can go alongside the non-IPA escaped solution and be 196 1.1 mrg used to query which vars escape the unit through a function. 197 1.1 mrg This is also required to make the escaped-HEAP trick work in IPA mode. 198 1.1 mrg 199 1.1 mrg We never put function decls in points-to sets so we do not 200 1.1 mrg keep the set of called functions for indirect calls. 201 1.1 mrg 202 1.1 mrg And probably more. */ 203 1.1 mrg 204 1.1 mrg static bool use_field_sensitive = true; 205 1.1 mrg static int in_ipa_mode = 0; 206 1.1 mrg 207 1.1 mrg /* Used for predecessor bitmaps. */ 208 1.1 mrg static bitmap_obstack predbitmap_obstack; 209 1.1 mrg 210 1.1 mrg /* Used for points-to sets. */ 211 1.1 mrg static bitmap_obstack pta_obstack; 212 1.1 mrg 213 1.1 mrg /* Used for oldsolution members of variables. */ 214 1.1 mrg static bitmap_obstack oldpta_obstack; 215 1.1 mrg 216 1.1 mrg /* Used for per-solver-iteration bitmaps. */ 217 1.1 mrg static bitmap_obstack iteration_obstack; 218 1.1 mrg 219 1.1 mrg static unsigned int create_variable_info_for (tree, const char *, bool); 220 1.1 mrg typedef struct constraint_graph *constraint_graph_t; 221 1.1 mrg static void unify_nodes (constraint_graph_t, unsigned int, unsigned int, bool); 222 1.1 mrg 223 1.1 mrg struct constraint; 224 1.1 mrg typedef struct constraint *constraint_t; 225 1.1 mrg 226 1.1 mrg 227 1.1 mrg #define EXECUTE_IF_IN_NONNULL_BITMAP(a, b, c, d) \ 228 1.1 mrg if (a) \ 229 1.1 mrg EXECUTE_IF_SET_IN_BITMAP (a, b, c, d) 230 1.1 mrg 231 1.1 mrg static struct constraint_stats 232 1.1 mrg { 233 1.1 mrg unsigned int total_vars; 234 1.1 mrg unsigned int nonpointer_vars; 235 1.1 mrg unsigned int unified_vars_static; 236 1.1 mrg unsigned int unified_vars_dynamic; 237 1.1 mrg unsigned int iterations; 238 1.1 mrg unsigned int num_edges; 239 1.1 mrg unsigned int num_implicit_edges; 240 1.1 mrg unsigned int points_to_sets_created; 241 1.1 mrg } stats; 242 1.1 mrg 243 1.1 mrg struct variable_info 244 1.1 mrg { 245 1.1 mrg /* ID of this variable */ 246 1.1 mrg unsigned int id; 247 1.1 mrg 248 1.1 mrg /* True if this is a variable created by the constraint analysis, such as 249 1.1 mrg heap variables and constraints we had to break up. */ 250 1.1 mrg unsigned int is_artificial_var : 1; 251 1.1 mrg 252 1.1 mrg /* True if this is a special variable whose solution set should not be 253 1.1 mrg changed. */ 254 1.1 mrg unsigned int is_special_var : 1; 255 1.1 mrg 256 1.1 mrg /* True for variables whose size is not known or variable. */ 257 1.1 mrg unsigned int is_unknown_size_var : 1; 258 1.1 mrg 259 1.1 mrg /* True for (sub-)fields that represent a whole variable. */ 260 1.1 mrg unsigned int is_full_var : 1; 261 1.1 mrg 262 1.1 mrg /* True if this is a heap variable. */ 263 1.1 mrg unsigned int is_heap_var : 1; 264 1.1 mrg 265 1.1 mrg /* True if this is a register variable. */ 266 1.1 mrg unsigned int is_reg_var : 1; 267 1.1 mrg 268 1.1 mrg /* True if this field may contain pointers. */ 269 1.1 mrg unsigned int may_have_pointers : 1; 270 1.1 mrg 271 1.1 mrg /* True if this field has only restrict qualified pointers. */ 272 1.1 mrg unsigned int only_restrict_pointers : 1; 273 1.1 mrg 274 1.1 mrg /* True if this represents a heap var created for a restrict qualified 275 1.1 mrg pointer. */ 276 1.1 mrg unsigned int is_restrict_var : 1; 277 1.1 mrg 278 1.1 mrg /* True if this represents a global variable. */ 279 1.1 mrg unsigned int is_global_var : 1; 280 1.1 mrg 281 1.1 mrg /* True if this represents a module escape point for IPA analysis. */ 282 1.1 mrg unsigned int is_ipa_escape_point : 1; 283 1.1 mrg 284 1.1 mrg /* True if this represents a IPA function info. */ 285 1.1 mrg unsigned int is_fn_info : 1; 286 1.1 mrg 287 1.1 mrg /* True if this appears as RHS in a ADDRESSOF constraint. */ 288 1.1 mrg unsigned int address_taken : 1; 289 1.1 mrg 290 1.1 mrg /* ??? Store somewhere better. */ 291 1.1 mrg unsigned short ruid; 292 1.1 mrg 293 1.1 mrg /* The ID of the variable for the next field in this structure 294 1.1 mrg or zero for the last field in this structure. */ 295 1.1 mrg unsigned next; 296 1.1 mrg 297 1.1 mrg /* The ID of the variable for the first field in this structure. */ 298 1.1 mrg unsigned head; 299 1.1 mrg 300 1.1 mrg /* Offset of this variable, in bits, from the base variable */ 301 1.1 mrg unsigned HOST_WIDE_INT offset; 302 1.1 mrg 303 1.1 mrg /* Size of the variable, in bits. */ 304 1.1 mrg unsigned HOST_WIDE_INT size; 305 1.1 mrg 306 1.1 mrg /* Full size of the base variable, in bits. */ 307 1.1 mrg unsigned HOST_WIDE_INT fullsize; 308 1.1 mrg 309 1.1 mrg /* In IPA mode the shadow UID in case the variable needs to be duplicated in 310 1.1 mrg the final points-to solution because it reaches its containing 311 1.1 mrg function recursively. Zero if none is needed. */ 312 1.1 mrg unsigned int shadow_var_uid; 313 1.1 mrg 314 1.1 mrg /* Name of this variable */ 315 1.1 mrg const char *name; 316 1.1 mrg 317 1.1 mrg /* Tree that this variable is associated with. */ 318 1.1 mrg tree decl; 319 1.1 mrg 320 1.1 mrg /* Points-to set for this variable. */ 321 1.1 mrg bitmap solution; 322 1.1 mrg 323 1.1 mrg /* Old points-to set for this variable. */ 324 1.1 mrg bitmap oldsolution; 325 1.1 mrg }; 326 1.1 mrg typedef struct variable_info *varinfo_t; 327 1.1 mrg 328 1.1 mrg static varinfo_t first_vi_for_offset (varinfo_t, unsigned HOST_WIDE_INT); 329 1.1 mrg static varinfo_t first_or_preceding_vi_for_offset (varinfo_t, 330 1.1 mrg unsigned HOST_WIDE_INT); 331 1.1 mrg static varinfo_t lookup_vi_for_tree (tree); 332 1.1 mrg static inline bool type_can_have_subvars (const_tree); 333 1.1 mrg static void make_param_constraints (varinfo_t); 334 1.1 mrg 335 1.1 mrg /* Pool of variable info structures. */ 336 1.1 mrg static object_allocator<variable_info> variable_info_pool 337 1.1 mrg ("Variable info pool"); 338 1.1 mrg 339 1.1 mrg /* Map varinfo to final pt_solution. */ 340 1.1 mrg static hash_map<varinfo_t, pt_solution *> *final_solutions; 341 1.1 mrg struct obstack final_solutions_obstack; 342 1.1 mrg 343 1.1 mrg /* Table of variable info structures for constraint variables. 344 1.1 mrg Indexed directly by variable info id. */ 345 1.1 mrg static vec<varinfo_t> varmap; 346 1.1 mrg 347 1.1 mrg /* Return the varmap element N */ 348 1.1 mrg 349 1.1 mrg static inline varinfo_t 350 1.1 mrg get_varinfo (unsigned int n) 351 1.1 mrg { 352 1.1 mrg return varmap[n]; 353 1.1 mrg } 354 1.1 mrg 355 1.1 mrg /* Return the next variable in the list of sub-variables of VI 356 1.1 mrg or NULL if VI is the last sub-variable. */ 357 1.1 mrg 358 1.1 mrg static inline varinfo_t 359 1.1 mrg vi_next (varinfo_t vi) 360 1.1 mrg { 361 1.1 mrg return get_varinfo (vi->next); 362 1.1 mrg } 363 1.1 mrg 364 1.1 mrg /* Static IDs for the special variables. Variable ID zero is unused 365 1.1 mrg and used as terminator for the sub-variable chain. */ 366 1.1 mrg enum { nothing_id = 1, anything_id = 2, string_id = 3, 367 1.1 mrg escaped_id = 4, nonlocal_id = 5, 368 1.1 mrg storedanything_id = 6, integer_id = 7 }; 369 1.1 mrg 370 1.1 mrg /* Return a new variable info structure consisting for a variable 371 1.1 mrg named NAME, and using constraint graph node NODE. Append it 372 1.1 mrg to the vector of variable info structures. */ 373 1.1 mrg 374 1.1 mrg static varinfo_t 375 1.1 mrg new_var_info (tree t, const char *name, bool add_id) 376 1.1 mrg { 377 1.1 mrg unsigned index = varmap.length (); 378 1.1 mrg varinfo_t ret = variable_info_pool.allocate (); 379 1.1 mrg 380 1.1 mrg if (dump_file && add_id) 381 1.1 mrg { 382 1.1 mrg char *tempname = xasprintf ("%s(%d)", name, index); 383 1.1 mrg name = ggc_strdup (tempname); 384 1.1 mrg free (tempname); 385 1.1 mrg } 386 1.1 mrg 387 1.1 mrg ret->id = index; 388 1.1 mrg ret->name = name; 389 1.1 mrg ret->decl = t; 390 1.1 mrg /* Vars without decl are artificial and do not have sub-variables. */ 391 1.1 mrg ret->is_artificial_var = (t == NULL_TREE); 392 1.1 mrg ret->is_special_var = false; 393 1.1 mrg ret->is_unknown_size_var = false; 394 1.1 mrg ret->is_full_var = (t == NULL_TREE); 395 1.1 mrg ret->is_heap_var = false; 396 1.1 mrg ret->may_have_pointers = true; 397 1.1 mrg ret->only_restrict_pointers = false; 398 1.1 mrg ret->is_restrict_var = false; 399 1.1 mrg ret->ruid = 0; 400 1.1 mrg ret->is_global_var = (t == NULL_TREE); 401 1.1 mrg ret->is_ipa_escape_point = false; 402 1.1 mrg ret->is_fn_info = false; 403 1.1 mrg ret->address_taken = false; 404 1.1 mrg if (t && DECL_P (t)) 405 1.1 mrg ret->is_global_var = (is_global_var (t) 406 1.1 mrg /* We have to treat even local register variables 407 1.1 mrg as escape points. */ 408 1.1 mrg || (VAR_P (t) && DECL_HARD_REGISTER (t))); 409 1.1 mrg ret->is_reg_var = (t && TREE_CODE (t) == SSA_NAME); 410 1.1 mrg ret->solution = BITMAP_ALLOC (&pta_obstack); 411 1.1 mrg ret->oldsolution = NULL; 412 1.1 mrg ret->next = 0; 413 1.1 mrg ret->shadow_var_uid = 0; 414 1.1 mrg ret->head = ret->id; 415 1.1 mrg 416 1.1 mrg stats.total_vars++; 417 1.1 mrg 418 1.1 mrg varmap.safe_push (ret); 419 1.1 mrg 420 1.1 mrg return ret; 421 1.1 mrg } 422 1.1 mrg 423 1.1 mrg /* A map mapping call statements to per-stmt variables for uses 424 1.1 mrg and clobbers specific to the call. */ 425 1.1 mrg static hash_map<gimple *, varinfo_t> *call_stmt_vars; 426 1.1 mrg 427 1.1 mrg /* Lookup or create the variable for the call statement CALL. */ 428 1.1 mrg 429 1.1 mrg static varinfo_t 430 1.1 mrg get_call_vi (gcall *call) 431 1.1 mrg { 432 1.1 mrg varinfo_t vi, vi2; 433 1.1 mrg 434 1.1 mrg bool existed; 435 1.1 mrg varinfo_t *slot_p = &call_stmt_vars->get_or_insert (call, &existed); 436 1.1 mrg if (existed) 437 1.1 mrg return *slot_p; 438 1.1 mrg 439 1.1 mrg vi = new_var_info (NULL_TREE, "CALLUSED", true); 440 1.1 mrg vi->offset = 0; 441 1.1 mrg vi->size = 1; 442 1.1 mrg vi->fullsize = 2; 443 1.1 mrg vi->is_full_var = true; 444 1.1 mrg vi->is_reg_var = true; 445 1.1 mrg 446 1.1 mrg vi2 = new_var_info (NULL_TREE, "CALLCLOBBERED", true); 447 1.1 mrg vi2->offset = 1; 448 1.1 mrg vi2->size = 1; 449 1.1 mrg vi2->fullsize = 2; 450 1.1 mrg vi2->is_full_var = true; 451 1.1 mrg vi2->is_reg_var = true; 452 1.1 mrg 453 1.1 mrg vi->next = vi2->id; 454 1.1 mrg 455 1.1 mrg *slot_p = vi; 456 1.1 mrg return vi; 457 1.1 mrg } 458 1.1 mrg 459 1.1 mrg /* Lookup the variable for the call statement CALL representing 460 1.1 mrg the uses. Returns NULL if there is nothing special about this call. */ 461 1.1 mrg 462 1.1 mrg static varinfo_t 463 1.1 mrg lookup_call_use_vi (gcall *call) 464 1.1 mrg { 465 1.1 mrg varinfo_t *slot_p = call_stmt_vars->get (call); 466 1.1 mrg if (slot_p) 467 1.1 mrg return *slot_p; 468 1.1 mrg 469 1.1 mrg return NULL; 470 1.1 mrg } 471 1.1 mrg 472 1.1 mrg /* Lookup the variable for the call statement CALL representing 473 1.1 mrg the clobbers. Returns NULL if there is nothing special about this call. */ 474 1.1 mrg 475 1.1 mrg static varinfo_t 476 1.1 mrg lookup_call_clobber_vi (gcall *call) 477 1.1 mrg { 478 1.1 mrg varinfo_t uses = lookup_call_use_vi (call); 479 1.1 mrg if (!uses) 480 1.1 mrg return NULL; 481 1.1 mrg 482 1.1 mrg return vi_next (uses); 483 1.1 mrg } 484 1.1 mrg 485 1.1 mrg /* Lookup or create the variable for the call statement CALL representing 486 1.1 mrg the uses. */ 487 1.1 mrg 488 1.1 mrg static varinfo_t 489 1.1 mrg get_call_use_vi (gcall *call) 490 1.1 mrg { 491 1.1 mrg return get_call_vi (call); 492 1.1 mrg } 493 1.1 mrg 494 1.1 mrg /* Lookup or create the variable for the call statement CALL representing 495 1.1 mrg the clobbers. */ 496 1.1 mrg 497 1.1 mrg static varinfo_t ATTRIBUTE_UNUSED 498 1.1 mrg get_call_clobber_vi (gcall *call) 499 1.1 mrg { 500 1.1 mrg return vi_next (get_call_vi (call)); 501 1.1 mrg } 502 1.1 mrg 503 1.1 mrg 504 1.1 mrg enum constraint_expr_type {SCALAR, DEREF, ADDRESSOF}; 505 1.1 mrg 506 1.1 mrg /* An expression that appears in a constraint. */ 507 1.1 mrg 508 1.1 mrg struct constraint_expr 509 1.1 mrg { 510 1.1 mrg /* Constraint type. */ 511 1.1 mrg constraint_expr_type type; 512 1.1 mrg 513 1.1 mrg /* Variable we are referring to in the constraint. */ 514 1.1 mrg unsigned int var; 515 1.1 mrg 516 1.1 mrg /* Offset, in bits, of this constraint from the beginning of 517 1.1 mrg variables it ends up referring to. 518 1.1 mrg 519 1.1 mrg IOW, in a deref constraint, we would deref, get the result set, 520 1.1 mrg then add OFFSET to each member. */ 521 1.1 mrg HOST_WIDE_INT offset; 522 1.1 mrg }; 523 1.1 mrg 524 1.1 mrg /* Use 0x8000... as special unknown offset. */ 525 1.1 mrg #define UNKNOWN_OFFSET HOST_WIDE_INT_MIN 526 1.1 mrg 527 1.1 mrg typedef struct constraint_expr ce_s; 528 1.1 mrg static void get_constraint_for_1 (tree, vec<ce_s> *, bool, bool); 529 1.1 mrg static void get_constraint_for (tree, vec<ce_s> *); 530 1.1 mrg static void get_constraint_for_rhs (tree, vec<ce_s> *); 531 1.1 mrg static void do_deref (vec<ce_s> *); 532 1.1 mrg 533 1.1 mrg /* Our set constraints are made up of two constraint expressions, one 534 1.1 mrg LHS, and one RHS. 535 1.1 mrg 536 1.1 mrg As described in the introduction, our set constraints each represent an 537 1.1 mrg operation between set valued variables. 538 1.1 mrg */ 539 1.1 mrg struct constraint 540 1.1 mrg { 541 1.1 mrg struct constraint_expr lhs; 542 1.1 mrg struct constraint_expr rhs; 543 1.1 mrg }; 544 1.1 mrg 545 1.1 mrg /* List of constraints that we use to build the constraint graph from. */ 546 1.1 mrg 547 1.1 mrg static vec<constraint_t> constraints; 548 1.1 mrg static object_allocator<constraint> constraint_pool ("Constraint pool"); 549 1.1 mrg 550 1.1 mrg /* The constraint graph is represented as an array of bitmaps 551 1.1 mrg containing successor nodes. */ 552 1.1 mrg 553 1.1 mrg struct constraint_graph 554 1.1 mrg { 555 1.1 mrg /* Size of this graph, which may be different than the number of 556 1.1 mrg nodes in the variable map. */ 557 1.1 mrg unsigned int size; 558 1.1 mrg 559 1.1 mrg /* Explicit successors of each node. */ 560 1.1 mrg bitmap *succs; 561 1.1 mrg 562 1.1 mrg /* Implicit predecessors of each node (Used for variable 563 1.1 mrg substitution). */ 564 1.1 mrg bitmap *implicit_preds; 565 1.1 mrg 566 1.1 mrg /* Explicit predecessors of each node (Used for variable substitution). */ 567 1.1 mrg bitmap *preds; 568 1.1 mrg 569 1.1 mrg /* Indirect cycle representatives, or -1 if the node has no indirect 570 1.1 mrg cycles. */ 571 1.1 mrg int *indirect_cycles; 572 1.1 mrg 573 1.1 mrg /* Representative node for a node. rep[a] == a unless the node has 574 1.1 mrg been unified. */ 575 1.1 mrg unsigned int *rep; 576 1.1 mrg 577 1.1 mrg /* Equivalence class representative for a label. This is used for 578 1.1 mrg variable substitution. */ 579 1.1 mrg int *eq_rep; 580 1.1 mrg 581 1.1 mrg /* Pointer equivalence label for a node. All nodes with the same 582 1.1 mrg pointer equivalence label can be unified together at some point 583 1.1 mrg (either during constraint optimization or after the constraint 584 1.1 mrg graph is built). */ 585 1.1 mrg unsigned int *pe; 586 1.1 mrg 587 1.1 mrg /* Pointer equivalence representative for a label. This is used to 588 1.1 mrg handle nodes that are pointer equivalent but not location 589 1.1 mrg equivalent. We can unite these once the addressof constraints 590 1.1 mrg are transformed into initial points-to sets. */ 591 1.1 mrg int *pe_rep; 592 1.1 mrg 593 1.1 mrg /* Pointer equivalence label for each node, used during variable 594 1.1 mrg substitution. */ 595 1.1 mrg unsigned int *pointer_label; 596 1.1 mrg 597 1.1 mrg /* Location equivalence label for each node, used during location 598 1.1 mrg equivalence finding. */ 599 1.1 mrg unsigned int *loc_label; 600 1.1 mrg 601 1.1 mrg /* Pointed-by set for each node, used during location equivalence 602 1.1 mrg finding. This is pointed-by rather than pointed-to, because it 603 1.1 mrg is constructed using the predecessor graph. */ 604 1.1 mrg bitmap *pointed_by; 605 1.1 mrg 606 1.1 mrg /* Points to sets for pointer equivalence. This is *not* the actual 607 1.1 mrg points-to sets for nodes. */ 608 1.1 mrg bitmap *points_to; 609 1.1 mrg 610 1.1 mrg /* Bitmap of nodes where the bit is set if the node is a direct 611 1.1 mrg node. Used for variable substitution. */ 612 1.1 mrg sbitmap direct_nodes; 613 1.1 mrg 614 1.1 mrg /* Bitmap of nodes where the bit is set if the node is address 615 1.1 mrg taken. Used for variable substitution. */ 616 1.1 mrg bitmap address_taken; 617 1.1 mrg 618 1.1 mrg /* Vector of complex constraints for each graph node. Complex 619 1.1 mrg constraints are those involving dereferences or offsets that are 620 1.1 mrg not 0. */ 621 1.1 mrg vec<constraint_t> *complex; 622 1.1 mrg }; 623 1.1 mrg 624 1.1 mrg static constraint_graph_t graph; 625 1.1 mrg 626 1.1 mrg /* During variable substitution and the offline version of indirect 627 1.1 mrg cycle finding, we create nodes to represent dereferences and 628 1.1 mrg address taken constraints. These represent where these start and 629 1.1 mrg end. */ 630 1.1 mrg #define FIRST_REF_NODE (varmap).length () 631 1.1 mrg #define LAST_REF_NODE (FIRST_REF_NODE + (FIRST_REF_NODE - 1)) 632 1.1 mrg 633 1.1 mrg /* Return the representative node for NODE, if NODE has been unioned 634 1.1 mrg with another NODE. 635 1.1 mrg This function performs path compression along the way to finding 636 1.1 mrg the representative. */ 637 1.1 mrg 638 1.1 mrg static unsigned int 639 1.1 mrg find (unsigned int node) 640 1.1 mrg { 641 1.1 mrg gcc_checking_assert (node < graph->size); 642 1.1 mrg if (graph->rep[node] != node) 643 1.1 mrg return graph->rep[node] = find (graph->rep[node]); 644 1.1 mrg return node; 645 1.1 mrg } 646 1.1 mrg 647 1.1 mrg /* Union the TO and FROM nodes to the TO nodes. 648 1.1 mrg Note that at some point in the future, we may want to do 649 1.1 mrg union-by-rank, in which case we are going to have to return the 650 1.1 mrg node we unified to. */ 651 1.1 mrg 652 1.1 mrg static bool 653 1.1 mrg unite (unsigned int to, unsigned int from) 654 1.1 mrg { 655 1.1 mrg gcc_checking_assert (to < graph->size && from < graph->size); 656 1.1 mrg if (to != from && graph->rep[from] != to) 657 1.1 mrg { 658 1.1 mrg graph->rep[from] = to; 659 1.1 mrg return true; 660 1.1 mrg } 661 1.1 mrg return false; 662 1.1 mrg } 663 1.1 mrg 664 1.1 mrg /* Create a new constraint consisting of LHS and RHS expressions. */ 665 1.1 mrg 666 1.1 mrg static constraint_t 667 1.1 mrg new_constraint (const struct constraint_expr lhs, 668 1.1 mrg const struct constraint_expr rhs) 669 1.1 mrg { 670 1.1 mrg constraint_t ret = constraint_pool.allocate (); 671 1.1 mrg ret->lhs = lhs; 672 1.1 mrg ret->rhs = rhs; 673 1.1 mrg return ret; 674 1.1 mrg } 675 1.1 mrg 676 1.1 mrg /* Print out constraint C to FILE. */ 677 1.1 mrg 678 1.1 mrg static void 679 1.1 mrg dump_constraint (FILE *file, constraint_t c) 680 1.1 mrg { 681 1.1 mrg if (c->lhs.type == ADDRESSOF) 682 1.1 mrg fprintf (file, "&"); 683 1.1 mrg else if (c->lhs.type == DEREF) 684 1.1 mrg fprintf (file, "*"); 685 1.1 mrg if (dump_file) 686 1.1 mrg fprintf (file, "%s", get_varinfo (c->lhs.var)->name); 687 1.1 mrg else 688 1.1 mrg fprintf (file, "V%d", c->lhs.var); 689 1.1 mrg if (c->lhs.offset == UNKNOWN_OFFSET) 690 1.1 mrg fprintf (file, " + UNKNOWN"); 691 1.1 mrg else if (c->lhs.offset != 0) 692 1.1 mrg fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->lhs.offset); 693 1.1 mrg fprintf (file, " = "); 694 1.1 mrg if (c->rhs.type == ADDRESSOF) 695 1.1 mrg fprintf (file, "&"); 696 1.1 mrg else if (c->rhs.type == DEREF) 697 1.1 mrg fprintf (file, "*"); 698 1.1 mrg if (dump_file) 699 1.1 mrg fprintf (file, "%s", get_varinfo (c->rhs.var)->name); 700 1.1 mrg else 701 1.1 mrg fprintf (file, "V%d", c->rhs.var); 702 1.1 mrg if (c->rhs.offset == UNKNOWN_OFFSET) 703 1.1 mrg fprintf (file, " + UNKNOWN"); 704 1.1 mrg else if (c->rhs.offset != 0) 705 1.1 mrg fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->rhs.offset); 706 1.1 mrg } 707 1.1 mrg 708 1.1 mrg 709 1.1 mrg void debug_constraint (constraint_t); 710 1.1 mrg void debug_constraints (void); 711 1.1 mrg void debug_constraint_graph (void); 712 1.1 mrg void debug_solution_for_var (unsigned int); 713 1.1 mrg void debug_sa_points_to_info (void); 714 1.1 mrg void debug_varinfo (varinfo_t); 715 1.1 mrg void debug_varmap (void); 716 1.1 mrg 717 1.1 mrg /* Print out constraint C to stderr. */ 718 1.1 mrg 719 1.1 mrg DEBUG_FUNCTION void 720 1.1 mrg debug_constraint (constraint_t c) 721 1.1 mrg { 722 1.1 mrg dump_constraint (stderr, c); 723 1.1 mrg fprintf (stderr, "\n"); 724 1.1 mrg } 725 1.1 mrg 726 1.1 mrg /* Print out all constraints to FILE */ 727 1.1 mrg 728 1.1 mrg static void 729 1.1 mrg dump_constraints (FILE *file, int from) 730 1.1 mrg { 731 1.1 mrg int i; 732 1.1 mrg constraint_t c; 733 1.1 mrg for (i = from; constraints.iterate (i, &c); i++) 734 1.1 mrg if (c) 735 1.1 mrg { 736 1.1 mrg dump_constraint (file, c); 737 1.1 mrg fprintf (file, "\n"); 738 1.1 mrg } 739 1.1 mrg } 740 1.1 mrg 741 1.1 mrg /* Print out all constraints to stderr. */ 742 1.1 mrg 743 1.1 mrg DEBUG_FUNCTION void 744 1.1 mrg debug_constraints (void) 745 1.1 mrg { 746 1.1 mrg dump_constraints (stderr, 0); 747 1.1 mrg } 748 1.1 mrg 749 1.1 mrg /* Print the constraint graph in dot format. */ 750 1.1 mrg 751 1.1 mrg static void 752 1.1 mrg dump_constraint_graph (FILE *file) 753 1.1 mrg { 754 1.1 mrg unsigned int i; 755 1.1 mrg 756 1.1 mrg /* Only print the graph if it has already been initialized: */ 757 1.1 mrg if (!graph) 758 1.1 mrg return; 759 1.1 mrg 760 1.1 mrg /* Prints the header of the dot file: */ 761 1.1 mrg fprintf (file, "strict digraph {\n"); 762 1.1 mrg fprintf (file, " node [\n shape = box\n ]\n"); 763 1.1 mrg fprintf (file, " edge [\n fontsize = \"12\"\n ]\n"); 764 1.1 mrg fprintf (file, "\n // List of nodes and complex constraints in " 765 1.1 mrg "the constraint graph:\n"); 766 1.1 mrg 767 1.1 mrg /* The next lines print the nodes in the graph together with the 768 1.1 mrg complex constraints attached to them. */ 769 1.1 mrg for (i = 1; i < graph->size; i++) 770 1.1 mrg { 771 1.1 mrg if (i == FIRST_REF_NODE) 772 1.1 mrg continue; 773 1.1 mrg if (find (i) != i) 774 1.1 mrg continue; 775 1.1 mrg if (i < FIRST_REF_NODE) 776 1.1 mrg fprintf (file, "\"%s\"", get_varinfo (i)->name); 777 1.1 mrg else 778 1.1 mrg fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name); 779 1.1 mrg if (graph->complex[i].exists ()) 780 1.1 mrg { 781 1.1 mrg unsigned j; 782 1.1 mrg constraint_t c; 783 1.1 mrg fprintf (file, " [label=\"\\N\\n"); 784 1.1 mrg for (j = 0; graph->complex[i].iterate (j, &c); ++j) 785 1.1 mrg { 786 1.1 mrg dump_constraint (file, c); 787 1.1 mrg fprintf (file, "\\l"); 788 1.1 mrg } 789 1.1 mrg fprintf (file, "\"]"); 790 1.1 mrg } 791 1.1 mrg fprintf (file, ";\n"); 792 1.1 mrg } 793 1.1 mrg 794 1.1 mrg /* Go over the edges. */ 795 1.1 mrg fprintf (file, "\n // Edges in the constraint graph:\n"); 796 1.1 mrg for (i = 1; i < graph->size; i++) 797 1.1 mrg { 798 1.1 mrg unsigned j; 799 1.1 mrg bitmap_iterator bi; 800 1.1 mrg if (find (i) != i) 801 1.1 mrg continue; 802 1.1 mrg EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[i], 0, j, bi) 803 1.1 mrg { 804 1.1 mrg unsigned to = find (j); 805 1.1 mrg if (i == to) 806 1.1 mrg continue; 807 1.1 mrg if (i < FIRST_REF_NODE) 808 1.1 mrg fprintf (file, "\"%s\"", get_varinfo (i)->name); 809 1.1 mrg else 810 1.1 mrg fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name); 811 1.1 mrg fprintf (file, " -> "); 812 1.1 mrg if (to < FIRST_REF_NODE) 813 1.1 mrg fprintf (file, "\"%s\"", get_varinfo (to)->name); 814 1.1 mrg else 815 1.1 mrg fprintf (file, "\"*%s\"", get_varinfo (to - FIRST_REF_NODE)->name); 816 1.1 mrg fprintf (file, ";\n"); 817 1.1 mrg } 818 1.1 mrg } 819 1.1 mrg 820 1.1 mrg /* Prints the tail of the dot file. */ 821 1.1 mrg fprintf (file, "}\n"); 822 1.1 mrg } 823 1.1 mrg 824 1.1 mrg /* Print out the constraint graph to stderr. */ 825 1.1 mrg 826 1.1 mrg DEBUG_FUNCTION void 827 1.1 mrg debug_constraint_graph (void) 828 1.1 mrg { 829 1.1 mrg dump_constraint_graph (stderr); 830 1.1 mrg } 831 1.1 mrg 832 1.1 mrg /* SOLVER FUNCTIONS 833 1.1 mrg 834 1.1 mrg The solver is a simple worklist solver, that works on the following 835 1.1 mrg algorithm: 836 1.1 mrg 837 1.1 mrg sbitmap changed_nodes = all zeroes; 838 1.1 mrg changed_count = 0; 839 1.1 mrg For each node that is not already collapsed: 840 1.1 mrg changed_count++; 841 1.1 mrg set bit in changed nodes 842 1.1 mrg 843 1.1 mrg while (changed_count > 0) 844 1.1 mrg { 845 1.1 mrg compute topological ordering for constraint graph 846 1.1 mrg 847 1.1 mrg find and collapse cycles in the constraint graph (updating 848 1.1 mrg changed if necessary) 849 1.1 mrg 850 1.1 mrg for each node (n) in the graph in topological order: 851 1.1 mrg changed_count--; 852 1.1 mrg 853 1.1 mrg Process each complex constraint associated with the node, 854 1.1 mrg updating changed if necessary. 855 1.1 mrg 856 1.1 mrg For each outgoing edge from n, propagate the solution from n to 857 1.1 mrg the destination of the edge, updating changed as necessary. 858 1.1 mrg 859 1.1 mrg } */ 860 1.1 mrg 861 1.1 mrg /* Return true if two constraint expressions A and B are equal. */ 862 1.1 mrg 863 1.1 mrg static bool 864 1.1 mrg constraint_expr_equal (struct constraint_expr a, struct constraint_expr b) 865 1.1 mrg { 866 1.1 mrg return a.type == b.type && a.var == b.var && a.offset == b.offset; 867 1.1 mrg } 868 1.1 mrg 869 1.1 mrg /* Return true if constraint expression A is less than constraint expression 870 1.1 mrg B. This is just arbitrary, but consistent, in order to give them an 871 1.1 mrg ordering. */ 872 1.1 mrg 873 1.1 mrg static bool 874 1.1 mrg constraint_expr_less (struct constraint_expr a, struct constraint_expr b) 875 1.1 mrg { 876 1.1 mrg if (a.type == b.type) 877 1.1 mrg { 878 1.1 mrg if (a.var == b.var) 879 1.1 mrg return a.offset < b.offset; 880 1.1 mrg else 881 1.1 mrg return a.var < b.var; 882 1.1 mrg } 883 1.1 mrg else 884 1.1 mrg return a.type < b.type; 885 1.1 mrg } 886 1.1 mrg 887 1.1 mrg /* Return true if constraint A is less than constraint B. This is just 888 1.1 mrg arbitrary, but consistent, in order to give them an ordering. */ 889 1.1 mrg 890 1.1 mrg static bool 891 1.1 mrg constraint_less (const constraint_t &a, const constraint_t &b) 892 1.1 mrg { 893 1.1 mrg if (constraint_expr_less (a->lhs, b->lhs)) 894 1.1 mrg return true; 895 1.1 mrg else if (constraint_expr_less (b->lhs, a->lhs)) 896 1.1 mrg return false; 897 1.1 mrg else 898 1.1 mrg return constraint_expr_less (a->rhs, b->rhs); 899 1.1 mrg } 900 1.1 mrg 901 1.1 mrg /* Return true if two constraints A and B are equal. */ 902 1.1 mrg 903 1.1 mrg static bool 904 1.1 mrg constraint_equal (struct constraint a, struct constraint b) 905 1.1 mrg { 906 1.1 mrg return constraint_expr_equal (a.lhs, b.lhs) 907 1.1 mrg && constraint_expr_equal (a.rhs, b.rhs); 908 1.1 mrg } 909 1.1 mrg 910 1.1 mrg 911 1.1 mrg /* Find a constraint LOOKFOR in the sorted constraint vector VEC */ 912 1.1 mrg 913 1.1 mrg static constraint_t 914 1.1 mrg constraint_vec_find (vec<constraint_t> vec, 915 1.1 mrg struct constraint lookfor) 916 1.1 mrg { 917 1.1 mrg unsigned int place; 918 1.1 mrg constraint_t found; 919 1.1 mrg 920 1.1 mrg if (!vec.exists ()) 921 1.1 mrg return NULL; 922 1.1 mrg 923 1.1 mrg place = vec.lower_bound (&lookfor, constraint_less); 924 1.1 mrg if (place >= vec.length ()) 925 1.1 mrg return NULL; 926 1.1 mrg found = vec[place]; 927 1.1 mrg if (!constraint_equal (*found, lookfor)) 928 1.1 mrg return NULL; 929 1.1 mrg return found; 930 1.1 mrg } 931 1.1 mrg 932 1.1 mrg /* Union two constraint vectors, TO and FROM. Put the result in TO. 933 1.1 mrg Returns true of TO set is changed. */ 934 1.1 mrg 935 1.1 mrg static bool 936 1.1 mrg constraint_set_union (vec<constraint_t> *to, 937 1.1 mrg vec<constraint_t> *from) 938 1.1 mrg { 939 1.1 mrg int i; 940 1.1 mrg constraint_t c; 941 1.1 mrg bool any_change = false; 942 1.1 mrg 943 1.1 mrg FOR_EACH_VEC_ELT (*from, i, c) 944 1.1 mrg { 945 1.1 mrg if (constraint_vec_find (*to, *c) == NULL) 946 1.1 mrg { 947 1.1 mrg unsigned int place = to->lower_bound (c, constraint_less); 948 1.1 mrg to->safe_insert (place, c); 949 1.1 mrg any_change = true; 950 1.1 mrg } 951 1.1 mrg } 952 1.1 mrg return any_change; 953 1.1 mrg } 954 1.1 mrg 955 1.1 mrg /* Expands the solution in SET to all sub-fields of variables included. */ 956 1.1 mrg 957 1.1 mrg static bitmap 958 1.1 mrg solution_set_expand (bitmap set, bitmap *expanded) 959 1.1 mrg { 960 1.1 mrg bitmap_iterator bi; 961 1.1 mrg unsigned j; 962 1.1 mrg 963 1.1 mrg if (*expanded) 964 1.1 mrg return *expanded; 965 1.1 mrg 966 1.1 mrg *expanded = BITMAP_ALLOC (&iteration_obstack); 967 1.1 mrg 968 1.1 mrg /* In a first pass expand to the head of the variables we need to 969 1.1 mrg add all sub-fields off. This avoids quadratic behavior. */ 970 1.1 mrg EXECUTE_IF_SET_IN_BITMAP (set, 0, j, bi) 971 1.1 mrg { 972 1.1 mrg varinfo_t v = get_varinfo (j); 973 1.1 mrg if (v->is_artificial_var 974 1.1 mrg || v->is_full_var) 975 1.1 mrg continue; 976 1.1 mrg bitmap_set_bit (*expanded, v->head); 977 1.1 mrg } 978 1.1 mrg 979 1.1 mrg /* In the second pass now expand all head variables with subfields. */ 980 1.1 mrg EXECUTE_IF_SET_IN_BITMAP (*expanded, 0, j, bi) 981 1.1 mrg { 982 1.1 mrg varinfo_t v = get_varinfo (j); 983 1.1 mrg if (v->head != j) 984 1.1 mrg continue; 985 1.1 mrg for (v = vi_next (v); v != NULL; v = vi_next (v)) 986 1.1 mrg bitmap_set_bit (*expanded, v->id); 987 1.1 mrg } 988 1.1 mrg 989 1.1 mrg /* And finally set the rest of the bits from SET. */ 990 1.1 mrg bitmap_ior_into (*expanded, set); 991 1.1 mrg 992 1.1 mrg return *expanded; 993 1.1 mrg } 994 1.1 mrg 995 1.1 mrg /* Union solution sets TO and DELTA, and add INC to each member of DELTA in the 996 1.1 mrg process. */ 997 1.1 mrg 998 1.1 mrg static bool 999 1.1 mrg set_union_with_increment (bitmap to, bitmap delta, HOST_WIDE_INT inc, 1000 1.1 mrg bitmap *expanded_delta) 1001 1.1 mrg { 1002 1.1 mrg bool changed = false; 1003 1.1 mrg bitmap_iterator bi; 1004 1.1 mrg unsigned int i; 1005 1.1 mrg 1006 1.1 mrg /* If the solution of DELTA contains anything it is good enough to transfer 1007 1.1 mrg this to TO. */ 1008 1.1 mrg if (bitmap_bit_p (delta, anything_id)) 1009 1.1 mrg return bitmap_set_bit (to, anything_id); 1010 1.1 mrg 1011 1.1 mrg /* If the offset is unknown we have to expand the solution to 1012 1.1 mrg all subfields. */ 1013 1.1 mrg if (inc == UNKNOWN_OFFSET) 1014 1.1 mrg { 1015 1.1 mrg delta = solution_set_expand (delta, expanded_delta); 1016 1.1 mrg changed |= bitmap_ior_into (to, delta); 1017 1.1 mrg return changed; 1018 1.1 mrg } 1019 1.1 mrg 1020 1.1 mrg /* For non-zero offset union the offsetted solution into the destination. */ 1021 1.1 mrg EXECUTE_IF_SET_IN_BITMAP (delta, 0, i, bi) 1022 1.1 mrg { 1023 1.1 mrg varinfo_t vi = get_varinfo (i); 1024 1.1 mrg 1025 1.1 mrg /* If this is a variable with just one field just set its bit 1026 1.1 mrg in the result. */ 1027 1.1 mrg if (vi->is_artificial_var 1028 1.1 mrg || vi->is_unknown_size_var 1029 1.1 mrg || vi->is_full_var) 1030 1.1 mrg changed |= bitmap_set_bit (to, i); 1031 1.1 mrg else 1032 1.1 mrg { 1033 1.1 mrg HOST_WIDE_INT fieldoffset = vi->offset + inc; 1034 1.1 mrg unsigned HOST_WIDE_INT size = vi->size; 1035 1.1 mrg 1036 1.1 mrg /* If the offset makes the pointer point to before the 1037 1.1 mrg variable use offset zero for the field lookup. */ 1038 1.1 mrg if (fieldoffset < 0) 1039 1.1 mrg vi = get_varinfo (vi->head); 1040 1.1 mrg else 1041 1.1 mrg vi = first_or_preceding_vi_for_offset (vi, fieldoffset); 1042 1.1 mrg 1043 1.1 mrg do 1044 1.1 mrg { 1045 1.1 mrg changed |= bitmap_set_bit (to, vi->id); 1046 1.1 mrg if (vi->is_full_var 1047 1.1 mrg || vi->next == 0) 1048 1.1 mrg break; 1049 1.1 mrg 1050 1.1 mrg /* We have to include all fields that overlap the current field 1051 1.1 mrg shifted by inc. */ 1052 1.1 mrg vi = vi_next (vi); 1053 1.1 mrg } 1054 1.1 mrg while (vi->offset < fieldoffset + size); 1055 1.1 mrg } 1056 1.1 mrg } 1057 1.1 mrg 1058 1.1 mrg return changed; 1059 1.1 mrg } 1060 1.1 mrg 1061 1.1 mrg /* Insert constraint C into the list of complex constraints for graph 1062 1.1 mrg node VAR. */ 1063 1.1 mrg 1064 1.1 mrg static void 1065 1.1 mrg insert_into_complex (constraint_graph_t graph, 1066 1.1 mrg unsigned int var, constraint_t c) 1067 1.1 mrg { 1068 1.1 mrg vec<constraint_t> complex = graph->complex[var]; 1069 1.1 mrg unsigned int place = complex.lower_bound (c, constraint_less); 1070 1.1 mrg 1071 1.1 mrg /* Only insert constraints that do not already exist. */ 1072 1.1 mrg if (place >= complex.length () 1073 1.1 mrg || !constraint_equal (*c, *complex[place])) 1074 1.1 mrg graph->complex[var].safe_insert (place, c); 1075 1.1 mrg } 1076 1.1 mrg 1077 1.1 mrg 1078 1.1 mrg /* Condense two variable nodes into a single variable node, by moving 1079 1.1 mrg all associated info from FROM to TO. Returns true if TO node's 1080 1.1 mrg constraint set changes after the merge. */ 1081 1.1 mrg 1082 1.1 mrg static bool 1083 1.1 mrg merge_node_constraints (constraint_graph_t graph, unsigned int to, 1084 1.1 mrg unsigned int from) 1085 1.1 mrg { 1086 1.1 mrg unsigned int i; 1087 1.1 mrg constraint_t c; 1088 1.1 mrg bool any_change = false; 1089 1.1 mrg 1090 1.1 mrg gcc_checking_assert (find (from) == to); 1091 1.1 mrg 1092 1.1 mrg /* Move all complex constraints from src node into to node */ 1093 1.1 mrg FOR_EACH_VEC_ELT (graph->complex[from], i, c) 1094 1.1 mrg { 1095 1.1 mrg /* In complex constraints for node FROM, we may have either 1096 1.1 mrg a = *FROM, and *FROM = a, or an offseted constraint which are 1097 1.1 mrg always added to the rhs node's constraints. */ 1098 1.1 mrg 1099 1.1 mrg if (c->rhs.type == DEREF) 1100 1.1 mrg c->rhs.var = to; 1101 1.1 mrg else if (c->lhs.type == DEREF) 1102 1.1 mrg c->lhs.var = to; 1103 1.1 mrg else 1104 1.1 mrg c->rhs.var = to; 1105 1.1 mrg 1106 1.1 mrg } 1107 1.1 mrg any_change = constraint_set_union (&graph->complex[to], 1108 1.1 mrg &graph->complex[from]); 1109 1.1 mrg graph->complex[from].release (); 1110 1.1 mrg return any_change; 1111 1.1 mrg } 1112 1.1 mrg 1113 1.1 mrg 1114 1.1 mrg /* Remove edges involving NODE from GRAPH. */ 1115 1.1 mrg 1116 1.1 mrg static void 1117 1.1 mrg clear_edges_for_node (constraint_graph_t graph, unsigned int node) 1118 1.1 mrg { 1119 1.1 mrg if (graph->succs[node]) 1120 1.1 mrg BITMAP_FREE (graph->succs[node]); 1121 1.1 mrg } 1122 1.1 mrg 1123 1.1 mrg /* Merge GRAPH nodes FROM and TO into node TO. */ 1124 1.1 mrg 1125 1.1 mrg static void 1126 1.1 mrg merge_graph_nodes (constraint_graph_t graph, unsigned int to, 1127 1.1 mrg unsigned int from) 1128 1.1 mrg { 1129 1.1 mrg if (graph->indirect_cycles[from] != -1) 1130 1.1 mrg { 1131 1.1 mrg /* If we have indirect cycles with the from node, and we have 1132 1.1 mrg none on the to node, the to node has indirect cycles from the 1133 1.1 mrg from node now that they are unified. 1134 1.1 mrg If indirect cycles exist on both, unify the nodes that they 1135 1.1 mrg are in a cycle with, since we know they are in a cycle with 1136 1.1 mrg each other. */ 1137 1.1 mrg if (graph->indirect_cycles[to] == -1) 1138 1.1 mrg graph->indirect_cycles[to] = graph->indirect_cycles[from]; 1139 1.1 mrg } 1140 1.1 mrg 1141 1.1 mrg /* Merge all the successor edges. */ 1142 1.1 mrg if (graph->succs[from]) 1143 1.1 mrg { 1144 1.1 mrg if (!graph->succs[to]) 1145 1.1 mrg graph->succs[to] = BITMAP_ALLOC (&pta_obstack); 1146 1.1 mrg bitmap_ior_into (graph->succs[to], 1147 1.1 mrg graph->succs[from]); 1148 1.1 mrg } 1149 1.1 mrg 1150 1.1 mrg clear_edges_for_node (graph, from); 1151 1.1 mrg } 1152 1.1 mrg 1153 1.1 mrg 1154 1.1 mrg /* Add an indirect graph edge to GRAPH, going from TO to FROM if 1155 1.1 mrg it doesn't exist in the graph already. */ 1156 1.1 mrg 1157 1.1 mrg static void 1158 1.1 mrg add_implicit_graph_edge (constraint_graph_t graph, unsigned int to, 1159 1.1 mrg unsigned int from) 1160 1.1 mrg { 1161 1.1 mrg if (to == from) 1162 1.1 mrg return; 1163 1.1 mrg 1164 1.1 mrg if (!graph->implicit_preds[to]) 1165 1.1 mrg graph->implicit_preds[to] = BITMAP_ALLOC (&predbitmap_obstack); 1166 1.1 mrg 1167 1.1 mrg if (bitmap_set_bit (graph->implicit_preds[to], from)) 1168 1.1 mrg stats.num_implicit_edges++; 1169 1.1 mrg } 1170 1.1 mrg 1171 1.1 mrg /* Add a predecessor graph edge to GRAPH, going from TO to FROM if 1172 1.1 mrg it doesn't exist in the graph already. 1173 1.1 mrg Return false if the edge already existed, true otherwise. */ 1174 1.1 mrg 1175 1.1 mrg static void 1176 1.1 mrg add_pred_graph_edge (constraint_graph_t graph, unsigned int to, 1177 1.1 mrg unsigned int from) 1178 1.1 mrg { 1179 1.1 mrg if (!graph->preds[to]) 1180 1.1 mrg graph->preds[to] = BITMAP_ALLOC (&predbitmap_obstack); 1181 1.1 mrg bitmap_set_bit (graph->preds[to], from); 1182 1.1 mrg } 1183 1.1 mrg 1184 1.1 mrg /* Add a graph edge to GRAPH, going from FROM to TO if 1185 1.1 mrg it doesn't exist in the graph already. 1186 1.1 mrg Return false if the edge already existed, true otherwise. */ 1187 1.1 mrg 1188 1.1 mrg static bool 1189 1.1 mrg add_graph_edge (constraint_graph_t graph, unsigned int to, 1190 1.1 mrg unsigned int from) 1191 1.1 mrg { 1192 1.1 mrg if (to == from) 1193 1.1 mrg { 1194 1.1 mrg return false; 1195 1.1 mrg } 1196 1.1 mrg else 1197 1.1 mrg { 1198 1.1 mrg bool r = false; 1199 1.1 mrg 1200 1.1 mrg if (!graph->succs[from]) 1201 1.1 mrg graph->succs[from] = BITMAP_ALLOC (&pta_obstack); 1202 1.1 mrg 1203 1.1 mrg /* The graph solving process does not avoid "triangles", thus 1204 1.1 mrg there can be multiple paths from a node to another involving 1205 1.1 mrg intermediate other nodes. That causes extra copying which is 1206 1.1 mrg most difficult to avoid when the intermediate node is ESCAPED 1207 1.1 mrg because there are no edges added from ESCAPED. Avoid 1208 1.1 mrg adding the direct edge FROM -> TO when we have FROM -> ESCAPED 1209 1.1 mrg and TO contains ESCAPED. 1210 1.1 mrg ??? Note this is only a heuristic, it does not prevent the 1211 1.1 mrg situation from occuring. The heuristic helps PR38474 and 1212 1.1 mrg PR99912 significantly. */ 1213 1.1 mrg if (to < FIRST_REF_NODE 1214 1.1 mrg && bitmap_bit_p (graph->succs[from], find (escaped_id)) 1215 1.1 mrg && bitmap_bit_p (get_varinfo (find (to))->solution, escaped_id)) 1216 1.1 mrg return false; 1217 1.1 mrg 1218 1.1 mrg if (bitmap_set_bit (graph->succs[from], to)) 1219 1.1 mrg { 1220 1.1 mrg r = true; 1221 1.1 mrg if (to < FIRST_REF_NODE && from < FIRST_REF_NODE) 1222 1.1 mrg stats.num_edges++; 1223 1.1 mrg } 1224 1.1 mrg return r; 1225 1.1 mrg } 1226 1.1 mrg } 1227 1.1 mrg 1228 1.1 mrg 1229 1.1 mrg /* Initialize the constraint graph structure to contain SIZE nodes. */ 1230 1.1 mrg 1231 1.1 mrg static void 1232 1.1 mrg init_graph (unsigned int size) 1233 1.1 mrg { 1234 1.1 mrg unsigned int j; 1235 1.1 mrg 1236 1.1 mrg graph = XCNEW (struct constraint_graph); 1237 1.1 mrg graph->size = size; 1238 1.1 mrg graph->succs = XCNEWVEC (bitmap, graph->size); 1239 1.1 mrg graph->indirect_cycles = XNEWVEC (int, graph->size); 1240 1.1 mrg graph->rep = XNEWVEC (unsigned int, graph->size); 1241 1.1 mrg /* ??? Macros do not support template types with multiple arguments, 1242 1.1 mrg so we use a typedef to work around it. */ 1243 1.1 mrg typedef vec<constraint_t> vec_constraint_t_heap; 1244 1.1 mrg graph->complex = XCNEWVEC (vec_constraint_t_heap, size); 1245 1.1 mrg graph->pe = XCNEWVEC (unsigned int, graph->size); 1246 1.1 mrg graph->pe_rep = XNEWVEC (int, graph->size); 1247 1.1 mrg 1248 1.1 mrg for (j = 0; j < graph->size; j++) 1249 1.1 mrg { 1250 1.1 mrg graph->rep[j] = j; 1251 1.1 mrg graph->pe_rep[j] = -1; 1252 1.1 mrg graph->indirect_cycles[j] = -1; 1253 1.1 mrg } 1254 1.1 mrg } 1255 1.1 mrg 1256 1.1 mrg /* Build the constraint graph, adding only predecessor edges right now. */ 1257 1.1 mrg 1258 1.1 mrg static void 1259 1.1 mrg build_pred_graph (void) 1260 1.1 mrg { 1261 1.1 mrg int i; 1262 1.1 mrg constraint_t c; 1263 1.1 mrg unsigned int j; 1264 1.1 mrg 1265 1.1 mrg graph->implicit_preds = XCNEWVEC (bitmap, graph->size); 1266 1.1 mrg graph->preds = XCNEWVEC (bitmap, graph->size); 1267 1.1 mrg graph->pointer_label = XCNEWVEC (unsigned int, graph->size); 1268 1.1 mrg graph->loc_label = XCNEWVEC (unsigned int, graph->size); 1269 1.1 mrg graph->pointed_by = XCNEWVEC (bitmap, graph->size); 1270 1.1 mrg graph->points_to = XCNEWVEC (bitmap, graph->size); 1271 1.1 mrg graph->eq_rep = XNEWVEC (int, graph->size); 1272 1.1 mrg graph->direct_nodes = sbitmap_alloc (graph->size); 1273 1.1 mrg graph->address_taken = BITMAP_ALLOC (&predbitmap_obstack); 1274 1.1 mrg bitmap_clear (graph->direct_nodes); 1275 1.1 mrg 1276 1.1 mrg for (j = 1; j < FIRST_REF_NODE; j++) 1277 1.1 mrg { 1278 1.1 mrg if (!get_varinfo (j)->is_special_var) 1279 1.1 mrg bitmap_set_bit (graph->direct_nodes, j); 1280 1.1 mrg } 1281 1.1 mrg 1282 1.1 mrg for (j = 0; j < graph->size; j++) 1283 1.1 mrg graph->eq_rep[j] = -1; 1284 1.1 mrg 1285 1.1 mrg for (j = 0; j < varmap.length (); j++) 1286 1.1 mrg graph->indirect_cycles[j] = -1; 1287 1.1 mrg 1288 1.1 mrg FOR_EACH_VEC_ELT (constraints, i, c) 1289 1.1 mrg { 1290 1.1 mrg struct constraint_expr lhs = c->lhs; 1291 1.1 mrg struct constraint_expr rhs = c->rhs; 1292 1.1 mrg unsigned int lhsvar = lhs.var; 1293 1.1 mrg unsigned int rhsvar = rhs.var; 1294 1.1 mrg 1295 1.1 mrg if (lhs.type == DEREF) 1296 1.1 mrg { 1297 1.1 mrg /* *x = y. */ 1298 1.1 mrg if (rhs.offset == 0 && lhs.offset == 0 && rhs.type == SCALAR) 1299 1.1 mrg add_pred_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar); 1300 1.1 mrg } 1301 1.1 mrg else if (rhs.type == DEREF) 1302 1.1 mrg { 1303 1.1 mrg /* x = *y */ 1304 1.1 mrg if (rhs.offset == 0 && lhs.offset == 0 && lhs.type == SCALAR) 1305 1.1 mrg add_pred_graph_edge (graph, lhsvar, FIRST_REF_NODE + rhsvar); 1306 1.1 mrg else 1307 1.1 mrg bitmap_clear_bit (graph->direct_nodes, lhsvar); 1308 1.1 mrg } 1309 1.1 mrg else if (rhs.type == ADDRESSOF) 1310 1.1 mrg { 1311 1.1 mrg varinfo_t v; 1312 1.1 mrg 1313 1.1 mrg /* x = &y */ 1314 1.1 mrg if (graph->points_to[lhsvar] == NULL) 1315 1.1 mrg graph->points_to[lhsvar] = BITMAP_ALLOC (&predbitmap_obstack); 1316 1.1 mrg bitmap_set_bit (graph->points_to[lhsvar], rhsvar); 1317 1.1 mrg 1318 1.1 mrg if (graph->pointed_by[rhsvar] == NULL) 1319 1.1 mrg graph->pointed_by[rhsvar] = BITMAP_ALLOC (&predbitmap_obstack); 1320 1.1 mrg bitmap_set_bit (graph->pointed_by[rhsvar], lhsvar); 1321 1.1 mrg 1322 1.1 mrg /* Implicitly, *x = y */ 1323 1.1 mrg add_implicit_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar); 1324 1.1 mrg 1325 1.1 mrg /* All related variables are no longer direct nodes. */ 1326 1.1 mrg bitmap_clear_bit (graph->direct_nodes, rhsvar); 1327 1.1 mrg v = get_varinfo (rhsvar); 1328 1.1 mrg if (!v->is_full_var) 1329 1.1 mrg { 1330 1.1 mrg v = get_varinfo (v->head); 1331 1.1 mrg do 1332 1.1 mrg { 1333 1.1 mrg bitmap_clear_bit (graph->direct_nodes, v->id); 1334 1.1 mrg v = vi_next (v); 1335 1.1 mrg } 1336 1.1 mrg while (v != NULL); 1337 1.1 mrg } 1338 1.1 mrg bitmap_set_bit (graph->address_taken, rhsvar); 1339 1.1 mrg } 1340 1.1 mrg else if (lhsvar > anything_id 1341 1.1 mrg && lhsvar != rhsvar && lhs.offset == 0 && rhs.offset == 0) 1342 1.1 mrg { 1343 1.1 mrg /* x = y */ 1344 1.1 mrg add_pred_graph_edge (graph, lhsvar, rhsvar); 1345 1.1 mrg /* Implicitly, *x = *y */ 1346 1.1 mrg add_implicit_graph_edge (graph, FIRST_REF_NODE + lhsvar, 1347 1.1 mrg FIRST_REF_NODE + rhsvar); 1348 1.1 mrg } 1349 1.1 mrg else if (lhs.offset != 0 || rhs.offset != 0) 1350 1.1 mrg { 1351 1.1 mrg if (rhs.offset != 0) 1352 1.1 mrg bitmap_clear_bit (graph->direct_nodes, lhs.var); 1353 1.1 mrg else if (lhs.offset != 0) 1354 1.1 mrg bitmap_clear_bit (graph->direct_nodes, rhs.var); 1355 1.1 mrg } 1356 1.1 mrg } 1357 1.1 mrg } 1358 1.1 mrg 1359 1.1 mrg /* Build the constraint graph, adding successor edges. */ 1360 1.1 mrg 1361 1.1 mrg static void 1362 1.1 mrg build_succ_graph (void) 1363 1.1 mrg { 1364 1.1 mrg unsigned i, t; 1365 1.1 mrg constraint_t c; 1366 1.1 mrg 1367 1.1 mrg FOR_EACH_VEC_ELT (constraints, i, c) 1368 1.1 mrg { 1369 1.1 mrg struct constraint_expr lhs; 1370 1.1 mrg struct constraint_expr rhs; 1371 1.1 mrg unsigned int lhsvar; 1372 1.1 mrg unsigned int rhsvar; 1373 1.1 mrg 1374 1.1 mrg if (!c) 1375 1.1 mrg continue; 1376 1.1 mrg 1377 1.1 mrg lhs = c->lhs; 1378 1.1 mrg rhs = c->rhs; 1379 1.1 mrg lhsvar = find (lhs.var); 1380 1.1 mrg rhsvar = find (rhs.var); 1381 1.1 mrg 1382 1.1 mrg if (lhs.type == DEREF) 1383 1.1 mrg { 1384 1.1 mrg if (rhs.offset == 0 && lhs.offset == 0 && rhs.type == SCALAR) 1385 1.1 mrg add_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar); 1386 1.1 mrg } 1387 1.1 mrg else if (rhs.type == DEREF) 1388 1.1 mrg { 1389 1.1 mrg if (rhs.offset == 0 && lhs.offset == 0 && lhs.type == SCALAR) 1390 1.1 mrg add_graph_edge (graph, lhsvar, FIRST_REF_NODE + rhsvar); 1391 1.1 mrg } 1392 1.1 mrg else if (rhs.type == ADDRESSOF) 1393 1.1 mrg { 1394 1.1 mrg /* x = &y */ 1395 1.1 mrg gcc_checking_assert (find (rhs.var) == rhs.var); 1396 1.1 mrg bitmap_set_bit (get_varinfo (lhsvar)->solution, rhsvar); 1397 1.1 mrg } 1398 1.1 mrg else if (lhsvar > anything_id 1399 1.1 mrg && lhsvar != rhsvar && lhs.offset == 0 && rhs.offset == 0) 1400 1.1 mrg { 1401 1.1 mrg add_graph_edge (graph, lhsvar, rhsvar); 1402 1.1 mrg } 1403 1.1 mrg } 1404 1.1 mrg 1405 1.1 mrg /* Add edges from STOREDANYTHING to all non-direct nodes that can 1406 1.1 mrg receive pointers. */ 1407 1.1 mrg t = find (storedanything_id); 1408 1.1 mrg for (i = integer_id + 1; i < FIRST_REF_NODE; ++i) 1409 1.1 mrg { 1410 1.1 mrg if (!bitmap_bit_p (graph->direct_nodes, i) 1411 1.1 mrg && get_varinfo (i)->may_have_pointers) 1412 1.1 mrg add_graph_edge (graph, find (i), t); 1413 1.1 mrg } 1414 1.1 mrg 1415 1.1 mrg /* Everything stored to ANYTHING also potentially escapes. */ 1416 1.1 mrg add_graph_edge (graph, find (escaped_id), t); 1417 1.1 mrg } 1418 1.1 mrg 1419 1.1 mrg 1420 1.1 mrg /* Changed variables on the last iteration. */ 1421 1.1 mrg static bitmap changed; 1422 1.1 mrg 1423 1.1 mrg /* Strongly Connected Component visitation info. */ 1424 1.1 mrg 1425 1.1 mrg class scc_info 1426 1.1 mrg { 1427 1.1 mrg public: 1428 1.1 mrg scc_info (size_t size); 1429 1.1 mrg ~scc_info (); 1430 1.1 mrg 1431 1.1 mrg auto_sbitmap visited; 1432 1.1 mrg auto_sbitmap deleted; 1433 1.1 mrg unsigned int *dfs; 1434 1.1 mrg unsigned int *node_mapping; 1435 1.1 mrg int current_index; 1436 1.1 mrg auto_vec<unsigned> scc_stack; 1437 1.1 mrg }; 1438 1.1 mrg 1439 1.1 mrg 1440 1.1 mrg /* Recursive routine to find strongly connected components in GRAPH. 1441 1.1 mrg SI is the SCC info to store the information in, and N is the id of current 1442 1.1 mrg graph node we are processing. 1443 1.1 mrg 1444 1.1 mrg This is Tarjan's strongly connected component finding algorithm, as 1445 1.1 mrg modified by Nuutila to keep only non-root nodes on the stack. 1446 1.1 mrg The algorithm can be found in "On finding the strongly connected 1447 1.1 mrg connected components in a directed graph" by Esko Nuutila and Eljas 1448 1.1 mrg Soisalon-Soininen, in Information Processing Letters volume 49, 1449 1.1 mrg number 1, pages 9-14. */ 1450 1.1 mrg 1451 1.1 mrg static void 1452 1.1 mrg scc_visit (constraint_graph_t graph, class scc_info *si, unsigned int n) 1453 1.1 mrg { 1454 1.1 mrg unsigned int i; 1455 1.1 mrg bitmap_iterator bi; 1456 1.1 mrg unsigned int my_dfs; 1457 1.1 mrg 1458 1.1 mrg bitmap_set_bit (si->visited, n); 1459 1.1 mrg si->dfs[n] = si->current_index ++; 1460 1.1 mrg my_dfs = si->dfs[n]; 1461 1.1 mrg 1462 1.1 mrg /* Visit all the successors. */ 1463 1.1 mrg EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[n], 0, i, bi) 1464 1.1 mrg { 1465 1.1 mrg unsigned int w; 1466 1.1 mrg 1467 1.1 mrg if (i > LAST_REF_NODE) 1468 1.1 mrg break; 1469 1.1 mrg 1470 1.1 mrg w = find (i); 1471 1.1 mrg if (bitmap_bit_p (si->deleted, w)) 1472 1.1 mrg continue; 1473 1.1 mrg 1474 1.1 mrg if (!bitmap_bit_p (si->visited, w)) 1475 1.1 mrg scc_visit (graph, si, w); 1476 1.1 mrg 1477 1.1 mrg unsigned int t = find (w); 1478 1.1 mrg gcc_checking_assert (find (n) == n); 1479 1.1 mrg if (si->dfs[t] < si->dfs[n]) 1480 1.1 mrg si->dfs[n] = si->dfs[t]; 1481 1.1 mrg } 1482 1.1 mrg 1483 1.1 mrg /* See if any components have been identified. */ 1484 1.1 mrg if (si->dfs[n] == my_dfs) 1485 1.1 mrg { 1486 1.1 mrg if (si->scc_stack.length () > 0 1487 1.1 mrg && si->dfs[si->scc_stack.last ()] >= my_dfs) 1488 1.1 mrg { 1489 1.1 mrg bitmap scc = BITMAP_ALLOC (NULL); 1490 1.1 mrg unsigned int lowest_node; 1491 1.1 mrg bitmap_iterator bi; 1492 1.1 mrg 1493 1.1 mrg bitmap_set_bit (scc, n); 1494 1.1 mrg 1495 1.1 mrg while (si->scc_stack.length () != 0 1496 1.1 mrg && si->dfs[si->scc_stack.last ()] >= my_dfs) 1497 1.1 mrg { 1498 1.1 mrg unsigned int w = si->scc_stack.pop (); 1499 1.1 mrg 1500 1.1 mrg bitmap_set_bit (scc, w); 1501 1.1 mrg } 1502 1.1 mrg 1503 1.1 mrg lowest_node = bitmap_first_set_bit (scc); 1504 1.1 mrg gcc_assert (lowest_node < FIRST_REF_NODE); 1505 1.1 mrg 1506 1.1 mrg /* Collapse the SCC nodes into a single node, and mark the 1507 1.1 mrg indirect cycles. */ 1508 1.1 mrg EXECUTE_IF_SET_IN_BITMAP (scc, 0, i, bi) 1509 1.1 mrg { 1510 1.1 mrg if (i < FIRST_REF_NODE) 1511 1.1 mrg { 1512 1.1 mrg if (unite (lowest_node, i)) 1513 1.1 mrg unify_nodes (graph, lowest_node, i, false); 1514 1.1 mrg } 1515 1.1 mrg else 1516 1.1 mrg { 1517 1.1 mrg unite (lowest_node, i); 1518 1.1 mrg graph->indirect_cycles[i - FIRST_REF_NODE] = lowest_node; 1519 1.1 mrg } 1520 1.1 mrg } 1521 1.1 mrg } 1522 1.1 mrg bitmap_set_bit (si->deleted, n); 1523 1.1 mrg } 1524 1.1 mrg else 1525 1.1 mrg si->scc_stack.safe_push (n); 1526 1.1 mrg } 1527 1.1 mrg 1528 1.1 mrg /* Unify node FROM into node TO, updating the changed count if 1529 1.1 mrg necessary when UPDATE_CHANGED is true. */ 1530 1.1 mrg 1531 1.1 mrg static void 1532 1.1 mrg unify_nodes (constraint_graph_t graph, unsigned int to, unsigned int from, 1533 1.1 mrg bool update_changed) 1534 1.1 mrg { 1535 1.1 mrg gcc_checking_assert (to != from && find (to) == to); 1536 1.1 mrg 1537 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 1538 1.1 mrg fprintf (dump_file, "Unifying %s to %s\n", 1539 1.1 mrg get_varinfo (from)->name, 1540 1.1 mrg get_varinfo (to)->name); 1541 1.1 mrg 1542 1.1 mrg if (update_changed) 1543 1.1 mrg stats.unified_vars_dynamic++; 1544 1.1 mrg else 1545 1.1 mrg stats.unified_vars_static++; 1546 1.1 mrg 1547 1.1 mrg merge_graph_nodes (graph, to, from); 1548 1.1 mrg if (merge_node_constraints (graph, to, from)) 1549 1.1 mrg { 1550 1.1 mrg if (update_changed) 1551 1.1 mrg bitmap_set_bit (changed, to); 1552 1.1 mrg } 1553 1.1 mrg 1554 1.1 mrg /* Mark TO as changed if FROM was changed. If TO was already marked 1555 1.1 mrg as changed, decrease the changed count. */ 1556 1.1 mrg 1557 1.1 mrg if (update_changed 1558 1.1 mrg && bitmap_clear_bit (changed, from)) 1559 1.1 mrg bitmap_set_bit (changed, to); 1560 1.1 mrg varinfo_t fromvi = get_varinfo (from); 1561 1.1 mrg if (fromvi->solution) 1562 1.1 mrg { 1563 1.1 mrg /* If the solution changes because of the merging, we need to mark 1564 1.1 mrg the variable as changed. */ 1565 1.1 mrg varinfo_t tovi = get_varinfo (to); 1566 1.1 mrg if (bitmap_ior_into (tovi->solution, fromvi->solution)) 1567 1.1 mrg { 1568 1.1 mrg if (update_changed) 1569 1.1 mrg bitmap_set_bit (changed, to); 1570 1.1 mrg } 1571 1.1 mrg 1572 1.1 mrg BITMAP_FREE (fromvi->solution); 1573 1.1 mrg if (fromvi->oldsolution) 1574 1.1 mrg BITMAP_FREE (fromvi->oldsolution); 1575 1.1 mrg 1576 1.1 mrg if (stats.iterations > 0 1577 1.1 mrg && tovi->oldsolution) 1578 1.1 mrg BITMAP_FREE (tovi->oldsolution); 1579 1.1 mrg } 1580 1.1 mrg if (graph->succs[to]) 1581 1.1 mrg bitmap_clear_bit (graph->succs[to], to); 1582 1.1 mrg } 1583 1.1 mrg 1584 1.1 mrg /* Process a constraint C that represents x = *(y + off), using DELTA as the 1585 1.1 mrg starting solution for y. */ 1586 1.1 mrg 1587 1.1 mrg static void 1588 1.1 mrg do_sd_constraint (constraint_graph_t graph, constraint_t c, 1589 1.1 mrg bitmap delta, bitmap *expanded_delta) 1590 1.1 mrg { 1591 1.1 mrg unsigned int lhs = c->lhs.var; 1592 1.1 mrg bool flag = false; 1593 1.1 mrg bitmap sol = get_varinfo (lhs)->solution; 1594 1.1 mrg unsigned int j; 1595 1.1 mrg bitmap_iterator bi; 1596 1.1 mrg HOST_WIDE_INT roffset = c->rhs.offset; 1597 1.1 mrg 1598 1.1 mrg /* Our IL does not allow this. */ 1599 1.1 mrg gcc_checking_assert (c->lhs.offset == 0); 1600 1.1 mrg 1601 1.1 mrg /* If the solution of Y contains anything it is good enough to transfer 1602 1.1 mrg this to the LHS. */ 1603 1.1 mrg if (bitmap_bit_p (delta, anything_id)) 1604 1.1 mrg { 1605 1.1 mrg flag |= bitmap_set_bit (sol, anything_id); 1606 1.1 mrg goto done; 1607 1.1 mrg } 1608 1.1 mrg 1609 1.1 mrg /* If we do not know at with offset the rhs is dereferenced compute 1610 1.1 mrg the reachability set of DELTA, conservatively assuming it is 1611 1.1 mrg dereferenced at all valid offsets. */ 1612 1.1 mrg if (roffset == UNKNOWN_OFFSET) 1613 1.1 mrg { 1614 1.1 mrg delta = solution_set_expand (delta, expanded_delta); 1615 1.1 mrg /* No further offset processing is necessary. */ 1616 1.1 mrg roffset = 0; 1617 1.1 mrg } 1618 1.1 mrg 1619 1.1 mrg /* For each variable j in delta (Sol(y)), add 1620 1.1 mrg an edge in the graph from j to x, and union Sol(j) into Sol(x). */ 1621 1.1 mrg EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi) 1622 1.1 mrg { 1623 1.1 mrg varinfo_t v = get_varinfo (j); 1624 1.1 mrg HOST_WIDE_INT fieldoffset = v->offset + roffset; 1625 1.1 mrg unsigned HOST_WIDE_INT size = v->size; 1626 1.1 mrg unsigned int t; 1627 1.1 mrg 1628 1.1 mrg if (v->is_full_var) 1629 1.1 mrg ; 1630 1.1 mrg else if (roffset != 0) 1631 1.1 mrg { 1632 1.1 mrg if (fieldoffset < 0) 1633 1.1 mrg v = get_varinfo (v->head); 1634 1.1 mrg else 1635 1.1 mrg v = first_or_preceding_vi_for_offset (v, fieldoffset); 1636 1.1 mrg } 1637 1.1 mrg 1638 1.1 mrg /* We have to include all fields that overlap the current field 1639 1.1 mrg shifted by roffset. */ 1640 1.1 mrg do 1641 1.1 mrg { 1642 1.1 mrg t = find (v->id); 1643 1.1 mrg 1644 1.1 mrg /* Adding edges from the special vars is pointless. 1645 1.1 mrg They don't have sets that can change. */ 1646 1.1 mrg if (get_varinfo (t)->is_special_var) 1647 1.1 mrg flag |= bitmap_ior_into (sol, get_varinfo (t)->solution); 1648 1.1 mrg /* Merging the solution from ESCAPED needlessly increases 1649 1.1 mrg the set. Use ESCAPED as representative instead. */ 1650 1.1 mrg else if (v->id == escaped_id) 1651 1.1 mrg flag |= bitmap_set_bit (sol, escaped_id); 1652 1.1 mrg else if (v->may_have_pointers 1653 1.1 mrg && add_graph_edge (graph, lhs, t)) 1654 1.1 mrg flag |= bitmap_ior_into (sol, get_varinfo (t)->solution); 1655 1.1 mrg 1656 1.1 mrg if (v->is_full_var 1657 1.1 mrg || v->next == 0) 1658 1.1 mrg break; 1659 1.1 mrg 1660 1.1 mrg v = vi_next (v); 1661 1.1 mrg } 1662 1.1 mrg while (v->offset < fieldoffset + size); 1663 1.1 mrg } 1664 1.1 mrg 1665 1.1 mrg done: 1666 1.1 mrg /* If the LHS solution changed, mark the var as changed. */ 1667 1.1 mrg if (flag) 1668 1.1 mrg { 1669 1.1 mrg get_varinfo (lhs)->solution = sol; 1670 1.1 mrg bitmap_set_bit (changed, lhs); 1671 1.1 mrg } 1672 1.1 mrg } 1673 1.1 mrg 1674 1.1 mrg /* Process a constraint C that represents *(x + off) = y using DELTA 1675 1.1 mrg as the starting solution for x. */ 1676 1.1 mrg 1677 1.1 mrg static void 1678 1.1 mrg do_ds_constraint (constraint_t c, bitmap delta, bitmap *expanded_delta) 1679 1.1 mrg { 1680 1.1 mrg unsigned int rhs = c->rhs.var; 1681 1.1 mrg bitmap sol = get_varinfo (rhs)->solution; 1682 1.1 mrg unsigned int j; 1683 1.1 mrg bitmap_iterator bi; 1684 1.1 mrg HOST_WIDE_INT loff = c->lhs.offset; 1685 1.1 mrg bool escaped_p = false; 1686 1.1 mrg 1687 1.1 mrg /* Our IL does not allow this. */ 1688 1.1 mrg gcc_checking_assert (c->rhs.offset == 0); 1689 1.1 mrg 1690 1.1 mrg /* If the solution of y contains ANYTHING simply use the ANYTHING 1691 1.1 mrg solution. This avoids needlessly increasing the points-to sets. */ 1692 1.1 mrg if (bitmap_bit_p (sol, anything_id)) 1693 1.1 mrg sol = get_varinfo (find (anything_id))->solution; 1694 1.1 mrg 1695 1.1 mrg /* If the solution for x contains ANYTHING we have to merge the 1696 1.1 mrg solution of y into all pointer variables which we do via 1697 1.1 mrg STOREDANYTHING. */ 1698 1.1 mrg if (bitmap_bit_p (delta, anything_id)) 1699 1.1 mrg { 1700 1.1 mrg unsigned t = find (storedanything_id); 1701 1.1 mrg if (add_graph_edge (graph, t, rhs)) 1702 1.1 mrg { 1703 1.1 mrg if (bitmap_ior_into (get_varinfo (t)->solution, sol)) 1704 1.1 mrg bitmap_set_bit (changed, t); 1705 1.1 mrg } 1706 1.1 mrg return; 1707 1.1 mrg } 1708 1.1 mrg 1709 1.1 mrg /* If we do not know at with offset the rhs is dereferenced compute 1710 1.1 mrg the reachability set of DELTA, conservatively assuming it is 1711 1.1 mrg dereferenced at all valid offsets. */ 1712 1.1 mrg if (loff == UNKNOWN_OFFSET) 1713 1.1 mrg { 1714 1.1 mrg delta = solution_set_expand (delta, expanded_delta); 1715 1.1 mrg loff = 0; 1716 1.1 mrg } 1717 1.1 mrg 1718 1.1 mrg /* For each member j of delta (Sol(x)), add an edge from y to j and 1719 1.1 mrg union Sol(y) into Sol(j) */ 1720 1.1 mrg EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi) 1721 1.1 mrg { 1722 1.1 mrg varinfo_t v = get_varinfo (j); 1723 1.1 mrg unsigned int t; 1724 1.1 mrg HOST_WIDE_INT fieldoffset = v->offset + loff; 1725 1.1 mrg unsigned HOST_WIDE_INT size = v->size; 1726 1.1 mrg 1727 1.1 mrg if (v->is_full_var) 1728 1.1 mrg ; 1729 1.1 mrg else if (loff != 0) 1730 1.1 mrg { 1731 1.1 mrg if (fieldoffset < 0) 1732 1.1 mrg v = get_varinfo (v->head); 1733 1.1 mrg else 1734 1.1 mrg v = first_or_preceding_vi_for_offset (v, fieldoffset); 1735 1.1 mrg } 1736 1.1 mrg 1737 1.1 mrg /* We have to include all fields that overlap the current field 1738 1.1 mrg shifted by loff. */ 1739 1.1 mrg do 1740 1.1 mrg { 1741 1.1 mrg if (v->may_have_pointers) 1742 1.1 mrg { 1743 1.1 mrg /* If v is a global variable then this is an escape point. */ 1744 1.1 mrg if (v->is_global_var 1745 1.1 mrg && !escaped_p) 1746 1.1 mrg { 1747 1.1 mrg t = find (escaped_id); 1748 1.1 mrg if (add_graph_edge (graph, t, rhs) 1749 1.1 mrg && bitmap_ior_into (get_varinfo (t)->solution, sol)) 1750 1.1 mrg bitmap_set_bit (changed, t); 1751 1.1 mrg /* Enough to let rhs escape once. */ 1752 1.1 mrg escaped_p = true; 1753 1.1 mrg } 1754 1.1 mrg 1755 1.1 mrg if (v->is_special_var) 1756 1.1 mrg break; 1757 1.1 mrg 1758 1.1 mrg t = find (v->id); 1759 1.1 mrg if (add_graph_edge (graph, t, rhs) 1760 1.1 mrg && bitmap_ior_into (get_varinfo (t)->solution, sol)) 1761 1.1 mrg bitmap_set_bit (changed, t); 1762 1.1 mrg } 1763 1.1 mrg 1764 1.1 mrg if (v->is_full_var 1765 1.1 mrg || v->next == 0) 1766 1.1 mrg break; 1767 1.1 mrg 1768 1.1 mrg v = vi_next (v); 1769 1.1 mrg } 1770 1.1 mrg while (v->offset < fieldoffset + size); 1771 1.1 mrg } 1772 1.1 mrg } 1773 1.1 mrg 1774 1.1 mrg /* Handle a non-simple (simple meaning requires no iteration), 1775 1.1 mrg constraint (IE *x = &y, x = *y, *x = y, and x = y with offsets involved). */ 1776 1.1 mrg 1777 1.1 mrg static void 1778 1.1 mrg do_complex_constraint (constraint_graph_t graph, constraint_t c, bitmap delta, 1779 1.1 mrg bitmap *expanded_delta) 1780 1.1 mrg { 1781 1.1 mrg if (c->lhs.type == DEREF) 1782 1.1 mrg { 1783 1.1 mrg if (c->rhs.type == ADDRESSOF) 1784 1.1 mrg { 1785 1.1 mrg gcc_unreachable (); 1786 1.1 mrg } 1787 1.1 mrg else 1788 1.1 mrg { 1789 1.1 mrg /* *x = y */ 1790 1.1 mrg do_ds_constraint (c, delta, expanded_delta); 1791 1.1 mrg } 1792 1.1 mrg } 1793 1.1 mrg else if (c->rhs.type == DEREF) 1794 1.1 mrg { 1795 1.1 mrg /* x = *y */ 1796 1.1 mrg if (!(get_varinfo (c->lhs.var)->is_special_var)) 1797 1.1 mrg do_sd_constraint (graph, c, delta, expanded_delta); 1798 1.1 mrg } 1799 1.1 mrg else 1800 1.1 mrg { 1801 1.1 mrg bitmap tmp; 1802 1.1 mrg bool flag = false; 1803 1.1 mrg 1804 1.1 mrg gcc_checking_assert (c->rhs.type == SCALAR && c->lhs.type == SCALAR 1805 1.1 mrg && c->rhs.offset != 0 && c->lhs.offset == 0); 1806 1.1 mrg tmp = get_varinfo (c->lhs.var)->solution; 1807 1.1 mrg 1808 1.1 mrg flag = set_union_with_increment (tmp, delta, c->rhs.offset, 1809 1.1 mrg expanded_delta); 1810 1.1 mrg 1811 1.1 mrg if (flag) 1812 1.1 mrg bitmap_set_bit (changed, c->lhs.var); 1813 1.1 mrg } 1814 1.1 mrg } 1815 1.1 mrg 1816 1.1 mrg /* Initialize and return a new SCC info structure. */ 1817 1.1 mrg 1818 1.1 mrg scc_info::scc_info (size_t size) : 1819 1.1 mrg visited (size), deleted (size), current_index (0), scc_stack (1) 1820 1.1 mrg { 1821 1.1 mrg bitmap_clear (visited); 1822 1.1 mrg bitmap_clear (deleted); 1823 1.1 mrg node_mapping = XNEWVEC (unsigned int, size); 1824 1.1 mrg dfs = XCNEWVEC (unsigned int, size); 1825 1.1 mrg 1826 1.1 mrg for (size_t i = 0; i < size; i++) 1827 1.1 mrg node_mapping[i] = i; 1828 1.1 mrg } 1829 1.1 mrg 1830 1.1 mrg /* Free an SCC info structure pointed to by SI */ 1831 1.1 mrg 1832 1.1 mrg scc_info::~scc_info () 1833 1.1 mrg { 1834 1.1 mrg free (node_mapping); 1835 1.1 mrg free (dfs); 1836 1.1 mrg } 1837 1.1 mrg 1838 1.1 mrg 1839 1.1 mrg /* Find indirect cycles in GRAPH that occur, using strongly connected 1840 1.1 mrg components, and note them in the indirect cycles map. 1841 1.1 mrg 1842 1.1 mrg This technique comes from Ben Hardekopf and Calvin Lin, 1843 1.1 mrg "It Pays to be Lazy: Fast and Accurate Pointer Analysis for Millions of 1844 1.1 mrg Lines of Code", submitted to PLDI 2007. */ 1845 1.1 mrg 1846 1.1 mrg static void 1847 1.1 mrg find_indirect_cycles (constraint_graph_t graph) 1848 1.1 mrg { 1849 1.1 mrg unsigned int i; 1850 1.1 mrg unsigned int size = graph->size; 1851 1.1 mrg scc_info si (size); 1852 1.1 mrg 1853 1.1 mrg for (i = 0; i < MIN (LAST_REF_NODE, size); i ++ ) 1854 1.1 mrg if (!bitmap_bit_p (si.visited, i) && find (i) == i) 1855 1.1 mrg scc_visit (graph, &si, i); 1856 1.1 mrg } 1857 1.1 mrg 1858 1.1 mrg /* Visit the graph in topological order starting at node N, and store the 1859 1.1 mrg order in TOPO_ORDER using VISITED to indicate visited nodes. */ 1860 1.1 mrg 1861 1.1 mrg static void 1862 1.1 mrg topo_visit (constraint_graph_t graph, vec<unsigned> &topo_order, 1863 1.1 mrg sbitmap visited, unsigned int n) 1864 1.1 mrg { 1865 1.1 mrg bitmap_iterator bi; 1866 1.1 mrg unsigned int j; 1867 1.1 mrg 1868 1.1 mrg bitmap_set_bit (visited, n); 1869 1.1 mrg 1870 1.1 mrg if (graph->succs[n]) 1871 1.1 mrg EXECUTE_IF_SET_IN_BITMAP (graph->succs[n], 0, j, bi) 1872 1.1 mrg { 1873 1.1 mrg unsigned k = find (j); 1874 1.1 mrg if (!bitmap_bit_p (visited, k)) 1875 1.1 mrg topo_visit (graph, topo_order, visited, k); 1876 1.1 mrg } 1877 1.1 mrg 1878 1.1 mrg topo_order.quick_push (n); 1879 1.1 mrg } 1880 1.1 mrg 1881 1.1 mrg /* Compute a topological ordering for GRAPH, and return the result. */ 1882 1.1 mrg 1883 1.1 mrg static auto_vec<unsigned> 1884 1.1 mrg compute_topo_order (constraint_graph_t graph) 1885 1.1 mrg { 1886 1.1 mrg unsigned int i; 1887 1.1 mrg unsigned int size = graph->size; 1888 1.1 mrg 1889 1.1 mrg auto_sbitmap visited (size); 1890 1.1 mrg bitmap_clear (visited); 1891 1.1 mrg 1892 1.1 mrg /* For the heuristic in add_graph_edge to work optimally make sure to 1893 1.1 mrg first visit the connected component of the graph containing 1894 1.1 mrg ESCAPED. Do this by extracting the connected component 1895 1.1 mrg with ESCAPED and append that to all other components as solve_graph 1896 1.1 mrg pops from the order. */ 1897 1.1 mrg auto_vec<unsigned> tail (size); 1898 1.1 mrg topo_visit (graph, tail, visited, find (escaped_id)); 1899 1.1 mrg 1900 1.1 mrg auto_vec<unsigned> topo_order (size); 1901 1.1 mrg 1902 1.1 mrg for (i = 0; i != size; ++i) 1903 1.1 mrg if (!bitmap_bit_p (visited, i) && find (i) == i) 1904 1.1 mrg topo_visit (graph, topo_order, visited, i); 1905 1.1 mrg 1906 1.1 mrg topo_order.splice (tail); 1907 1.1 mrg return topo_order; 1908 1.1 mrg } 1909 1.1 mrg 1910 1.1 mrg /* Structure used to for hash value numbering of pointer equivalence 1911 1.1 mrg classes. */ 1912 1.1 mrg 1913 1.1 mrg typedef struct equiv_class_label 1914 1.1 mrg { 1915 1.1 mrg hashval_t hashcode; 1916 1.1 mrg unsigned int equivalence_class; 1917 1.1 mrg bitmap labels; 1918 1.1 mrg } *equiv_class_label_t; 1919 1.1 mrg typedef const struct equiv_class_label *const_equiv_class_label_t; 1920 1.1 mrg 1921 1.1 mrg /* Equiv_class_label hashtable helpers. */ 1922 1.1 mrg 1923 1.1 mrg struct equiv_class_hasher : nofree_ptr_hash <equiv_class_label> 1924 1.1 mrg { 1925 1.1 mrg static inline hashval_t hash (const equiv_class_label *); 1926 1.1 mrg static inline bool equal (const equiv_class_label *, 1927 1.1 mrg const equiv_class_label *); 1928 1.1 mrg }; 1929 1.1 mrg 1930 1.1 mrg /* Hash function for a equiv_class_label_t */ 1931 1.1 mrg 1932 1.1 mrg inline hashval_t 1933 1.1 mrg equiv_class_hasher::hash (const equiv_class_label *ecl) 1934 1.1 mrg { 1935 1.1 mrg return ecl->hashcode; 1936 1.1 mrg } 1937 1.1 mrg 1938 1.1 mrg /* Equality function for two equiv_class_label_t's. */ 1939 1.1 mrg 1940 1.1 mrg inline bool 1941 1.1 mrg equiv_class_hasher::equal (const equiv_class_label *eql1, 1942 1.1 mrg const equiv_class_label *eql2) 1943 1.1 mrg { 1944 1.1 mrg return (eql1->hashcode == eql2->hashcode 1945 1.1 mrg && bitmap_equal_p (eql1->labels, eql2->labels)); 1946 1.1 mrg } 1947 1.1 mrg 1948 1.1 mrg /* A hashtable for mapping a bitmap of labels->pointer equivalence 1949 1.1 mrg classes. */ 1950 1.1 mrg static hash_table<equiv_class_hasher> *pointer_equiv_class_table; 1951 1.1 mrg 1952 1.1 mrg /* A hashtable for mapping a bitmap of labels->location equivalence 1953 1.1 mrg classes. */ 1954 1.1 mrg static hash_table<equiv_class_hasher> *location_equiv_class_table; 1955 1.1 mrg 1956 1.1 mrg struct obstack equiv_class_obstack; 1957 1.1 mrg 1958 1.1 mrg /* Lookup a equivalence class in TABLE by the bitmap of LABELS with 1959 1.1 mrg hash HAS it contains. Sets *REF_LABELS to the bitmap LABELS 1960 1.1 mrg is equivalent to. */ 1961 1.1 mrg 1962 1.1 mrg static equiv_class_label * 1963 1.1 mrg equiv_class_lookup_or_add (hash_table<equiv_class_hasher> *table, 1964 1.1 mrg bitmap labels) 1965 1.1 mrg { 1966 1.1 mrg equiv_class_label **slot; 1967 1.1 mrg equiv_class_label ecl; 1968 1.1 mrg 1969 1.1 mrg ecl.labels = labels; 1970 1.1 mrg ecl.hashcode = bitmap_hash (labels); 1971 1.1 mrg slot = table->find_slot (&ecl, INSERT); 1972 1.1 mrg if (!*slot) 1973 1.1 mrg { 1974 1.1 mrg *slot = XOBNEW (&equiv_class_obstack, struct equiv_class_label); 1975 1.1 mrg (*slot)->labels = labels; 1976 1.1 mrg (*slot)->hashcode = ecl.hashcode; 1977 1.1 mrg (*slot)->equivalence_class = 0; 1978 1.1 mrg } 1979 1.1 mrg 1980 1.1 mrg return *slot; 1981 1.1 mrg } 1982 1.1 mrg 1983 1.1 mrg /* Perform offline variable substitution. 1984 1.1 mrg 1985 1.1 mrg This is a worst case quadratic time way of identifying variables 1986 1.1 mrg that must have equivalent points-to sets, including those caused by 1987 1.1 mrg static cycles, and single entry subgraphs, in the constraint graph. 1988 1.1 mrg 1989 1.1 mrg The technique is described in "Exploiting Pointer and Location 1990 1.1 mrg Equivalence to Optimize Pointer Analysis. In the 14th International 1991 1.1 mrg Static Analysis Symposium (SAS), August 2007." It is known as the 1992 1.1 mrg "HU" algorithm, and is equivalent to value numbering the collapsed 1993 1.1 mrg constraint graph including evaluating unions. 1994 1.1 mrg 1995 1.1 mrg The general method of finding equivalence classes is as follows: 1996 1.1 mrg Add fake nodes (REF nodes) and edges for *a = b and a = *b constraints. 1997 1.1 mrg Initialize all non-REF nodes to be direct nodes. 1998 1.1 mrg For each constraint a = a U {b}, we set pts(a) = pts(a) u {fresh 1999 1.1 mrg variable} 2000 1.1 mrg For each constraint containing the dereference, we also do the same 2001 1.1 mrg thing. 2002 1.1 mrg 2003 1.1 mrg We then compute SCC's in the graph and unify nodes in the same SCC, 2004 1.1 mrg including pts sets. 2005 1.1 mrg 2006 1.1 mrg For each non-collapsed node x: 2007 1.1 mrg Visit all unvisited explicit incoming edges. 2008 1.1 mrg Ignoring all non-pointers, set pts(x) = Union of pts(a) for y 2009 1.1 mrg where y->x. 2010 1.1 mrg Lookup the equivalence class for pts(x). 2011 1.1 mrg If we found one, equivalence_class(x) = found class. 2012 1.1 mrg Otherwise, equivalence_class(x) = new class, and new_class is 2013 1.1 mrg added to the lookup table. 2014 1.1 mrg 2015 1.1 mrg All direct nodes with the same equivalence class can be replaced 2016 1.1 mrg with a single representative node. 2017 1.1 mrg All unlabeled nodes (label == 0) are not pointers and all edges 2018 1.1 mrg involving them can be eliminated. 2019 1.1 mrg We perform these optimizations during rewrite_constraints 2020 1.1 mrg 2021 1.1 mrg In addition to pointer equivalence class finding, we also perform 2022 1.1 mrg location equivalence class finding. This is the set of variables 2023 1.1 mrg that always appear together in points-to sets. We use this to 2024 1.1 mrg compress the size of the points-to sets. */ 2025 1.1 mrg 2026 1.1 mrg /* Current maximum pointer equivalence class id. */ 2027 1.1 mrg static int pointer_equiv_class; 2028 1.1 mrg 2029 1.1 mrg /* Current maximum location equivalence class id. */ 2030 1.1 mrg static int location_equiv_class; 2031 1.1 mrg 2032 1.1 mrg /* Recursive routine to find strongly connected components in GRAPH, 2033 1.1 mrg and label it's nodes with DFS numbers. */ 2034 1.1 mrg 2035 1.1 mrg static void 2036 1.1 mrg condense_visit (constraint_graph_t graph, class scc_info *si, unsigned int n) 2037 1.1 mrg { 2038 1.1 mrg unsigned int i; 2039 1.1 mrg bitmap_iterator bi; 2040 1.1 mrg unsigned int my_dfs; 2041 1.1 mrg 2042 1.1 mrg gcc_checking_assert (si->node_mapping[n] == n); 2043 1.1 mrg bitmap_set_bit (si->visited, n); 2044 1.1 mrg si->dfs[n] = si->current_index ++; 2045 1.1 mrg my_dfs = si->dfs[n]; 2046 1.1 mrg 2047 1.1 mrg /* Visit all the successors. */ 2048 1.1 mrg EXECUTE_IF_IN_NONNULL_BITMAP (graph->preds[n], 0, i, bi) 2049 1.1 mrg { 2050 1.1 mrg unsigned int w = si->node_mapping[i]; 2051 1.1 mrg 2052 1.1 mrg if (bitmap_bit_p (si->deleted, w)) 2053 1.1 mrg continue; 2054 1.1 mrg 2055 1.1 mrg if (!bitmap_bit_p (si->visited, w)) 2056 1.1 mrg condense_visit (graph, si, w); 2057 1.1 mrg 2058 1.1 mrg unsigned int t = si->node_mapping[w]; 2059 1.1 mrg gcc_checking_assert (si->node_mapping[n] == n); 2060 1.1 mrg if (si->dfs[t] < si->dfs[n]) 2061 1.1 mrg si->dfs[n] = si->dfs[t]; 2062 1.1 mrg } 2063 1.1 mrg 2064 1.1 mrg /* Visit all the implicit predecessors. */ 2065 1.1 mrg EXECUTE_IF_IN_NONNULL_BITMAP (graph->implicit_preds[n], 0, i, bi) 2066 1.1 mrg { 2067 1.1 mrg unsigned int w = si->node_mapping[i]; 2068 1.1 mrg 2069 1.1 mrg if (bitmap_bit_p (si->deleted, w)) 2070 1.1 mrg continue; 2071 1.1 mrg 2072 1.1 mrg if (!bitmap_bit_p (si->visited, w)) 2073 1.1 mrg condense_visit (graph, si, w); 2074 1.1 mrg 2075 1.1 mrg unsigned int t = si->node_mapping[w]; 2076 1.1 mrg gcc_assert (si->node_mapping[n] == n); 2077 1.1 mrg if (si->dfs[t] < si->dfs[n]) 2078 1.1 mrg si->dfs[n] = si->dfs[t]; 2079 1.1 mrg } 2080 1.1 mrg 2081 1.1 mrg /* See if any components have been identified. */ 2082 1.1 mrg if (si->dfs[n] == my_dfs) 2083 1.1 mrg { 2084 1.1 mrg if (si->scc_stack.length () != 0 2085 1.1 mrg && si->dfs[si->scc_stack.last ()] >= my_dfs) 2086 1.1 mrg { 2087 1.1 mrg /* Find the first node of the SCC and do non-bitmap work. */ 2088 1.1 mrg bool direct_p = true; 2089 1.1 mrg unsigned first = si->scc_stack.length (); 2090 1.1 mrg do 2091 1.1 mrg { 2092 1.1 mrg --first; 2093 1.1 mrg unsigned int w = si->scc_stack[first]; 2094 1.1 mrg si->node_mapping[w] = n; 2095 1.1 mrg if (!bitmap_bit_p (graph->direct_nodes, w)) 2096 1.1 mrg direct_p = false; 2097 1.1 mrg } 2098 1.1 mrg while (first > 0 2099 1.1 mrg && si->dfs[si->scc_stack[first - 1]] >= my_dfs); 2100 1.1 mrg if (!direct_p) 2101 1.1 mrg bitmap_clear_bit (graph->direct_nodes, n); 2102 1.1 mrg 2103 1.1 mrg /* Want to reduce to node n, push that first. */ 2104 1.1 mrg si->scc_stack.reserve (1); 2105 1.1 mrg si->scc_stack.quick_push (si->scc_stack[first]); 2106 1.1 mrg si->scc_stack[first] = n; 2107 1.1 mrg 2108 1.1 mrg unsigned scc_size = si->scc_stack.length () - first; 2109 1.1 mrg unsigned split = scc_size / 2; 2110 1.1 mrg unsigned carry = scc_size - split * 2; 2111 1.1 mrg while (split > 0) 2112 1.1 mrg { 2113 1.1 mrg for (unsigned i = 0; i < split; ++i) 2114 1.1 mrg { 2115 1.1 mrg unsigned a = si->scc_stack[first + i]; 2116 1.1 mrg unsigned b = si->scc_stack[first + split + carry + i]; 2117 1.1 mrg 2118 1.1 mrg /* Unify our nodes. */ 2119 1.1 mrg if (graph->preds[b]) 2120 1.1 mrg { 2121 1.1 mrg if (!graph->preds[a]) 2122 1.1 mrg std::swap (graph->preds[a], graph->preds[b]); 2123 1.1 mrg else 2124 1.1 mrg bitmap_ior_into_and_free (graph->preds[a], 2125 1.1 mrg &graph->preds[b]); 2126 1.1 mrg } 2127 1.1 mrg if (graph->implicit_preds[b]) 2128 1.1 mrg { 2129 1.1 mrg if (!graph->implicit_preds[a]) 2130 1.1 mrg std::swap (graph->implicit_preds[a], 2131 1.1 mrg graph->implicit_preds[b]); 2132 1.1 mrg else 2133 1.1 mrg bitmap_ior_into_and_free (graph->implicit_preds[a], 2134 1.1 mrg &graph->implicit_preds[b]); 2135 1.1 mrg } 2136 1.1 mrg if (graph->points_to[b]) 2137 1.1 mrg { 2138 1.1 mrg if (!graph->points_to[a]) 2139 1.1 mrg std::swap (graph->points_to[a], graph->points_to[b]); 2140 1.1 mrg else 2141 1.1 mrg bitmap_ior_into_and_free (graph->points_to[a], 2142 1.1 mrg &graph->points_to[b]); 2143 1.1 mrg } 2144 1.1 mrg } 2145 1.1 mrg unsigned remain = split + carry; 2146 1.1 mrg split = remain / 2; 2147 1.1 mrg carry = remain - split * 2; 2148 1.1 mrg } 2149 1.1 mrg /* Actually pop the SCC. */ 2150 1.1 mrg si->scc_stack.truncate (first); 2151 1.1 mrg } 2152 1.1 mrg bitmap_set_bit (si->deleted, n); 2153 1.1 mrg } 2154 1.1 mrg else 2155 1.1 mrg si->scc_stack.safe_push (n); 2156 1.1 mrg } 2157 1.1 mrg 2158 1.1 mrg /* Label pointer equivalences. 2159 1.1 mrg 2160 1.1 mrg This performs a value numbering of the constraint graph to 2161 1.1 mrg discover which variables will always have the same points-to sets 2162 1.1 mrg under the current set of constraints. 2163 1.1 mrg 2164 1.1 mrg The way it value numbers is to store the set of points-to bits 2165 1.1 mrg generated by the constraints and graph edges. This is just used as a 2166 1.1 mrg hash and equality comparison. The *actual set of points-to bits* is 2167 1.1 mrg completely irrelevant, in that we don't care about being able to 2168 1.1 mrg extract them later. 2169 1.1 mrg 2170 1.1 mrg The equality values (currently bitmaps) just have to satisfy a few 2171 1.1 mrg constraints, the main ones being: 2172 1.1 mrg 1. The combining operation must be order independent. 2173 1.1 mrg 2. The end result of a given set of operations must be unique iff the 2174 1.1 mrg combination of input values is unique 2175 1.1 mrg 3. Hashable. */ 2176 1.1 mrg 2177 1.1 mrg static void 2178 1.1 mrg label_visit (constraint_graph_t graph, class scc_info *si, unsigned int n) 2179 1.1 mrg { 2180 1.1 mrg unsigned int i, first_pred; 2181 1.1 mrg bitmap_iterator bi; 2182 1.1 mrg 2183 1.1 mrg bitmap_set_bit (si->visited, n); 2184 1.1 mrg 2185 1.1 mrg /* Label and union our incoming edges's points to sets. */ 2186 1.1 mrg first_pred = -1U; 2187 1.1 mrg EXECUTE_IF_IN_NONNULL_BITMAP (graph->preds[n], 0, i, bi) 2188 1.1 mrg { 2189 1.1 mrg unsigned int w = si->node_mapping[i]; 2190 1.1 mrg if (!bitmap_bit_p (si->visited, w)) 2191 1.1 mrg label_visit (graph, si, w); 2192 1.1 mrg 2193 1.1 mrg /* Skip unused edges */ 2194 1.1 mrg if (w == n || graph->pointer_label[w] == 0) 2195 1.1 mrg continue; 2196 1.1 mrg 2197 1.1 mrg if (graph->points_to[w]) 2198 1.1 mrg { 2199 1.1 mrg if (!graph->points_to[n]) 2200 1.1 mrg { 2201 1.1 mrg if (first_pred == -1U) 2202 1.1 mrg first_pred = w; 2203 1.1 mrg else 2204 1.1 mrg { 2205 1.1 mrg graph->points_to[n] = BITMAP_ALLOC (&predbitmap_obstack); 2206 1.1 mrg bitmap_ior (graph->points_to[n], 2207 1.1 mrg graph->points_to[first_pred], 2208 1.1 mrg graph->points_to[w]); 2209 1.1 mrg } 2210 1.1 mrg } 2211 1.1 mrg else 2212 1.1 mrg bitmap_ior_into (graph->points_to[n], graph->points_to[w]); 2213 1.1 mrg } 2214 1.1 mrg } 2215 1.1 mrg 2216 1.1 mrg /* Indirect nodes get fresh variables and a new pointer equiv class. */ 2217 1.1 mrg if (!bitmap_bit_p (graph->direct_nodes, n)) 2218 1.1 mrg { 2219 1.1 mrg if (!graph->points_to[n]) 2220 1.1 mrg { 2221 1.1 mrg graph->points_to[n] = BITMAP_ALLOC (&predbitmap_obstack); 2222 1.1 mrg if (first_pred != -1U) 2223 1.1 mrg bitmap_copy (graph->points_to[n], graph->points_to[first_pred]); 2224 1.1 mrg } 2225 1.1 mrg bitmap_set_bit (graph->points_to[n], FIRST_REF_NODE + n); 2226 1.1 mrg graph->pointer_label[n] = pointer_equiv_class++; 2227 1.1 mrg equiv_class_label_t ecl; 2228 1.1 mrg ecl = equiv_class_lookup_or_add (pointer_equiv_class_table, 2229 1.1 mrg graph->points_to[n]); 2230 1.1 mrg ecl->equivalence_class = graph->pointer_label[n]; 2231 1.1 mrg return; 2232 1.1 mrg } 2233 1.1 mrg 2234 1.1 mrg /* If there was only a single non-empty predecessor the pointer equiv 2235 1.1 mrg class is the same. */ 2236 1.1 mrg if (!graph->points_to[n]) 2237 1.1 mrg { 2238 1.1 mrg if (first_pred != -1U) 2239 1.1 mrg { 2240 1.1 mrg graph->pointer_label[n] = graph->pointer_label[first_pred]; 2241 1.1 mrg graph->points_to[n] = graph->points_to[first_pred]; 2242 1.1 mrg } 2243 1.1 mrg return; 2244 1.1 mrg } 2245 1.1 mrg 2246 1.1 mrg if (!bitmap_empty_p (graph->points_to[n])) 2247 1.1 mrg { 2248 1.1 mrg equiv_class_label_t ecl; 2249 1.1 mrg ecl = equiv_class_lookup_or_add (pointer_equiv_class_table, 2250 1.1 mrg graph->points_to[n]); 2251 1.1 mrg if (ecl->equivalence_class == 0) 2252 1.1 mrg ecl->equivalence_class = pointer_equiv_class++; 2253 1.1 mrg else 2254 1.1 mrg { 2255 1.1 mrg BITMAP_FREE (graph->points_to[n]); 2256 1.1 mrg graph->points_to[n] = ecl->labels; 2257 1.1 mrg } 2258 1.1 mrg graph->pointer_label[n] = ecl->equivalence_class; 2259 1.1 mrg } 2260 1.1 mrg } 2261 1.1 mrg 2262 1.1 mrg /* Print the pred graph in dot format. */ 2263 1.1 mrg 2264 1.1 mrg static void 2265 1.1 mrg dump_pred_graph (class scc_info *si, FILE *file) 2266 1.1 mrg { 2267 1.1 mrg unsigned int i; 2268 1.1 mrg 2269 1.1 mrg /* Only print the graph if it has already been initialized: */ 2270 1.1 mrg if (!graph) 2271 1.1 mrg return; 2272 1.1 mrg 2273 1.1 mrg /* Prints the header of the dot file: */ 2274 1.1 mrg fprintf (file, "strict digraph {\n"); 2275 1.1 mrg fprintf (file, " node [\n shape = box\n ]\n"); 2276 1.1 mrg fprintf (file, " edge [\n fontsize = \"12\"\n ]\n"); 2277 1.1 mrg fprintf (file, "\n // List of nodes and complex constraints in " 2278 1.1 mrg "the constraint graph:\n"); 2279 1.1 mrg 2280 1.1 mrg /* The next lines print the nodes in the graph together with the 2281 1.1 mrg complex constraints attached to them. */ 2282 1.1 mrg for (i = 1; i < graph->size; i++) 2283 1.1 mrg { 2284 1.1 mrg if (i == FIRST_REF_NODE) 2285 1.1 mrg continue; 2286 1.1 mrg if (si->node_mapping[i] != i) 2287 1.1 mrg continue; 2288 1.1 mrg if (i < FIRST_REF_NODE) 2289 1.1 mrg fprintf (file, "\"%s\"", get_varinfo (i)->name); 2290 1.1 mrg else 2291 1.1 mrg fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name); 2292 1.1 mrg if (graph->points_to[i] 2293 1.1 mrg && !bitmap_empty_p (graph->points_to[i])) 2294 1.1 mrg { 2295 1.1 mrg if (i < FIRST_REF_NODE) 2296 1.1 mrg fprintf (file, "[label=\"%s = {", get_varinfo (i)->name); 2297 1.1 mrg else 2298 1.1 mrg fprintf (file, "[label=\"*%s = {", 2299 1.1 mrg get_varinfo (i - FIRST_REF_NODE)->name); 2300 1.1 mrg unsigned j; 2301 1.1 mrg bitmap_iterator bi; 2302 1.1 mrg EXECUTE_IF_SET_IN_BITMAP (graph->points_to[i], 0, j, bi) 2303 1.1 mrg fprintf (file, " %d", j); 2304 1.1 mrg fprintf (file, " }\"]"); 2305 1.1 mrg } 2306 1.1 mrg fprintf (file, ";\n"); 2307 1.1 mrg } 2308 1.1 mrg 2309 1.1 mrg /* Go over the edges. */ 2310 1.1 mrg fprintf (file, "\n // Edges in the constraint graph:\n"); 2311 1.1 mrg for (i = 1; i < graph->size; i++) 2312 1.1 mrg { 2313 1.1 mrg unsigned j; 2314 1.1 mrg bitmap_iterator bi; 2315 1.1 mrg if (si->node_mapping[i] != i) 2316 1.1 mrg continue; 2317 1.1 mrg EXECUTE_IF_IN_NONNULL_BITMAP (graph->preds[i], 0, j, bi) 2318 1.1 mrg { 2319 1.1 mrg unsigned from = si->node_mapping[j]; 2320 1.1 mrg if (from < FIRST_REF_NODE) 2321 1.1 mrg fprintf (file, "\"%s\"", get_varinfo (from)->name); 2322 1.1 mrg else 2323 1.1 mrg fprintf (file, "\"*%s\"", get_varinfo (from - FIRST_REF_NODE)->name); 2324 1.1 mrg fprintf (file, " -> "); 2325 1.1 mrg if (i < FIRST_REF_NODE) 2326 1.1 mrg fprintf (file, "\"%s\"", get_varinfo (i)->name); 2327 1.1 mrg else 2328 1.1 mrg fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name); 2329 1.1 mrg fprintf (file, ";\n"); 2330 1.1 mrg } 2331 1.1 mrg } 2332 1.1 mrg 2333 1.1 mrg /* Prints the tail of the dot file. */ 2334 1.1 mrg fprintf (file, "}\n"); 2335 1.1 mrg } 2336 1.1 mrg 2337 1.1 mrg /* Perform offline variable substitution, discovering equivalence 2338 1.1 mrg classes, and eliminating non-pointer variables. */ 2339 1.1 mrg 2340 1.1 mrg static class scc_info * 2341 1.1 mrg perform_var_substitution (constraint_graph_t graph) 2342 1.1 mrg { 2343 1.1 mrg unsigned int i; 2344 1.1 mrg unsigned int size = graph->size; 2345 1.1 mrg scc_info *si = new scc_info (size); 2346 1.1 mrg 2347 1.1 mrg bitmap_obstack_initialize (&iteration_obstack); 2348 1.1 mrg gcc_obstack_init (&equiv_class_obstack); 2349 1.1 mrg pointer_equiv_class_table = new hash_table<equiv_class_hasher> (511); 2350 1.1 mrg location_equiv_class_table 2351 1.1 mrg = new hash_table<equiv_class_hasher> (511); 2352 1.1 mrg pointer_equiv_class = 1; 2353 1.1 mrg location_equiv_class = 1; 2354 1.1 mrg 2355 1.1 mrg /* Condense the nodes, which means to find SCC's, count incoming 2356 1.1 mrg predecessors, and unite nodes in SCC's. */ 2357 1.1 mrg for (i = 1; i < FIRST_REF_NODE; i++) 2358 1.1 mrg if (!bitmap_bit_p (si->visited, si->node_mapping[i])) 2359 1.1 mrg condense_visit (graph, si, si->node_mapping[i]); 2360 1.1 mrg 2361 1.1 mrg if (dump_file && (dump_flags & TDF_GRAPH)) 2362 1.1 mrg { 2363 1.1 mrg fprintf (dump_file, "\n\n// The constraint graph before var-substitution " 2364 1.1 mrg "in dot format:\n"); 2365 1.1 mrg dump_pred_graph (si, dump_file); 2366 1.1 mrg fprintf (dump_file, "\n\n"); 2367 1.1 mrg } 2368 1.1 mrg 2369 1.1 mrg bitmap_clear (si->visited); 2370 1.1 mrg /* Actually the label the nodes for pointer equivalences */ 2371 1.1 mrg for (i = 1; i < FIRST_REF_NODE; i++) 2372 1.1 mrg if (!bitmap_bit_p (si->visited, si->node_mapping[i])) 2373 1.1 mrg label_visit (graph, si, si->node_mapping[i]); 2374 1.1 mrg 2375 1.1 mrg /* Calculate location equivalence labels. */ 2376 1.1 mrg for (i = 1; i < FIRST_REF_NODE; i++) 2377 1.1 mrg { 2378 1.1 mrg bitmap pointed_by; 2379 1.1 mrg bitmap_iterator bi; 2380 1.1 mrg unsigned int j; 2381 1.1 mrg 2382 1.1 mrg if (!graph->pointed_by[i]) 2383 1.1 mrg continue; 2384 1.1 mrg pointed_by = BITMAP_ALLOC (&iteration_obstack); 2385 1.1 mrg 2386 1.1 mrg /* Translate the pointed-by mapping for pointer equivalence 2387 1.1 mrg labels. */ 2388 1.1 mrg EXECUTE_IF_SET_IN_BITMAP (graph->pointed_by[i], 0, j, bi) 2389 1.1 mrg { 2390 1.1 mrg bitmap_set_bit (pointed_by, 2391 1.1 mrg graph->pointer_label[si->node_mapping[j]]); 2392 1.1 mrg } 2393 1.1 mrg /* The original pointed_by is now dead. */ 2394 1.1 mrg BITMAP_FREE (graph->pointed_by[i]); 2395 1.1 mrg 2396 1.1 mrg /* Look up the location equivalence label if one exists, or make 2397 1.1 mrg one otherwise. */ 2398 1.1 mrg equiv_class_label_t ecl; 2399 1.1 mrg ecl = equiv_class_lookup_or_add (location_equiv_class_table, pointed_by); 2400 1.1 mrg if (ecl->equivalence_class == 0) 2401 1.1 mrg ecl->equivalence_class = location_equiv_class++; 2402 1.1 mrg else 2403 1.1 mrg { 2404 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 2405 1.1 mrg fprintf (dump_file, "Found location equivalence for node %s\n", 2406 1.1 mrg get_varinfo (i)->name); 2407 1.1 mrg BITMAP_FREE (pointed_by); 2408 1.1 mrg } 2409 1.1 mrg graph->loc_label[i] = ecl->equivalence_class; 2410 1.1 mrg 2411 1.1 mrg } 2412 1.1 mrg 2413 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 2414 1.1 mrg for (i = 1; i < FIRST_REF_NODE; i++) 2415 1.1 mrg { 2416 1.1 mrg unsigned j = si->node_mapping[i]; 2417 1.1 mrg if (j != i) 2418 1.1 mrg { 2419 1.1 mrg fprintf (dump_file, "%s node id %d ", 2420 1.1 mrg bitmap_bit_p (graph->direct_nodes, i) 2421 1.1 mrg ? "Direct" : "Indirect", i); 2422 1.1 mrg if (i < FIRST_REF_NODE) 2423 1.1 mrg fprintf (dump_file, "\"%s\"", get_varinfo (i)->name); 2424 1.1 mrg else 2425 1.1 mrg fprintf (dump_file, "\"*%s\"", 2426 1.1 mrg get_varinfo (i - FIRST_REF_NODE)->name); 2427 1.1 mrg fprintf (dump_file, " mapped to SCC leader node id %d ", j); 2428 1.1 mrg if (j < FIRST_REF_NODE) 2429 1.1 mrg fprintf (dump_file, "\"%s\"\n", get_varinfo (j)->name); 2430 1.1 mrg else 2431 1.1 mrg fprintf (dump_file, "\"*%s\"\n", 2432 1.1 mrg get_varinfo (j - FIRST_REF_NODE)->name); 2433 1.1 mrg } 2434 1.1 mrg else 2435 1.1 mrg { 2436 1.1 mrg fprintf (dump_file, 2437 1.1 mrg "Equivalence classes for %s node id %d ", 2438 1.1 mrg bitmap_bit_p (graph->direct_nodes, i) 2439 1.1 mrg ? "direct" : "indirect", i); 2440 1.1 mrg if (i < FIRST_REF_NODE) 2441 1.1 mrg fprintf (dump_file, "\"%s\"", get_varinfo (i)->name); 2442 1.1 mrg else 2443 1.1 mrg fprintf (dump_file, "\"*%s\"", 2444 1.1 mrg get_varinfo (i - FIRST_REF_NODE)->name); 2445 1.1 mrg fprintf (dump_file, 2446 1.1 mrg ": pointer %d, location %d\n", 2447 1.1 mrg graph->pointer_label[i], graph->loc_label[i]); 2448 1.1 mrg } 2449 1.1 mrg } 2450 1.1 mrg 2451 1.1 mrg /* Quickly eliminate our non-pointer variables. */ 2452 1.1 mrg 2453 1.1 mrg for (i = 1; i < FIRST_REF_NODE; i++) 2454 1.1 mrg { 2455 1.1 mrg unsigned int node = si->node_mapping[i]; 2456 1.1 mrg 2457 1.1 mrg if (graph->pointer_label[node] == 0) 2458 1.1 mrg { 2459 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 2460 1.1 mrg fprintf (dump_file, 2461 1.1 mrg "%s is a non-pointer variable, eliminating edges.\n", 2462 1.1 mrg get_varinfo (node)->name); 2463 1.1 mrg stats.nonpointer_vars++; 2464 1.1 mrg clear_edges_for_node (graph, node); 2465 1.1 mrg } 2466 1.1 mrg } 2467 1.1 mrg 2468 1.1 mrg return si; 2469 1.1 mrg } 2470 1.1 mrg 2471 1.1 mrg /* Free information that was only necessary for variable 2472 1.1 mrg substitution. */ 2473 1.1 mrg 2474 1.1 mrg static void 2475 1.1 mrg free_var_substitution_info (class scc_info *si) 2476 1.1 mrg { 2477 1.1 mrg delete si; 2478 1.1 mrg free (graph->pointer_label); 2479 1.1 mrg free (graph->loc_label); 2480 1.1 mrg free (graph->pointed_by); 2481 1.1 mrg free (graph->points_to); 2482 1.1 mrg free (graph->eq_rep); 2483 1.1 mrg sbitmap_free (graph->direct_nodes); 2484 1.1 mrg delete pointer_equiv_class_table; 2485 1.1 mrg pointer_equiv_class_table = NULL; 2486 1.1 mrg delete location_equiv_class_table; 2487 1.1 mrg location_equiv_class_table = NULL; 2488 1.1 mrg obstack_free (&equiv_class_obstack, NULL); 2489 1.1 mrg bitmap_obstack_release (&iteration_obstack); 2490 1.1 mrg } 2491 1.1 mrg 2492 1.1 mrg /* Return an existing node that is equivalent to NODE, which has 2493 1.1 mrg equivalence class LABEL, if one exists. Return NODE otherwise. */ 2494 1.1 mrg 2495 1.1 mrg static unsigned int 2496 1.1 mrg find_equivalent_node (constraint_graph_t graph, 2497 1.1 mrg unsigned int node, unsigned int label) 2498 1.1 mrg { 2499 1.1 mrg /* If the address version of this variable is unused, we can 2500 1.1 mrg substitute it for anything else with the same label. 2501 1.1 mrg Otherwise, we know the pointers are equivalent, but not the 2502 1.1 mrg locations, and we can unite them later. */ 2503 1.1 mrg 2504 1.1 mrg if (!bitmap_bit_p (graph->address_taken, node)) 2505 1.1 mrg { 2506 1.1 mrg gcc_checking_assert (label < graph->size); 2507 1.1 mrg 2508 1.1 mrg if (graph->eq_rep[label] != -1) 2509 1.1 mrg { 2510 1.1 mrg /* Unify the two variables since we know they are equivalent. */ 2511 1.1 mrg if (unite (graph->eq_rep[label], node)) 2512 1.1 mrg unify_nodes (graph, graph->eq_rep[label], node, false); 2513 1.1 mrg return graph->eq_rep[label]; 2514 1.1 mrg } 2515 1.1 mrg else 2516 1.1 mrg { 2517 1.1 mrg graph->eq_rep[label] = node; 2518 1.1 mrg graph->pe_rep[label] = node; 2519 1.1 mrg } 2520 1.1 mrg } 2521 1.1 mrg else 2522 1.1 mrg { 2523 1.1 mrg gcc_checking_assert (label < graph->size); 2524 1.1 mrg graph->pe[node] = label; 2525 1.1 mrg if (graph->pe_rep[label] == -1) 2526 1.1 mrg graph->pe_rep[label] = node; 2527 1.1 mrg } 2528 1.1 mrg 2529 1.1 mrg return node; 2530 1.1 mrg } 2531 1.1 mrg 2532 1.1 mrg /* Unite pointer equivalent but not location equivalent nodes in 2533 1.1 mrg GRAPH. This may only be performed once variable substitution is 2534 1.1 mrg finished. */ 2535 1.1 mrg 2536 1.1 mrg static void 2537 1.1 mrg unite_pointer_equivalences (constraint_graph_t graph) 2538 1.1 mrg { 2539 1.1 mrg unsigned int i; 2540 1.1 mrg 2541 1.1 mrg /* Go through the pointer equivalences and unite them to their 2542 1.1 mrg representative, if they aren't already. */ 2543 1.1 mrg for (i = 1; i < FIRST_REF_NODE; i++) 2544 1.1 mrg { 2545 1.1 mrg unsigned int label = graph->pe[i]; 2546 1.1 mrg if (label) 2547 1.1 mrg { 2548 1.1 mrg int label_rep = graph->pe_rep[label]; 2549 1.1 mrg 2550 1.1 mrg if (label_rep == -1) 2551 1.1 mrg continue; 2552 1.1 mrg 2553 1.1 mrg label_rep = find (label_rep); 2554 1.1 mrg if (label_rep >= 0 && unite (label_rep, find (i))) 2555 1.1 mrg unify_nodes (graph, label_rep, i, false); 2556 1.1 mrg } 2557 1.1 mrg } 2558 1.1 mrg } 2559 1.1 mrg 2560 1.1 mrg /* Move complex constraints to the GRAPH nodes they belong to. */ 2561 1.1 mrg 2562 1.1 mrg static void 2563 1.1 mrg move_complex_constraints (constraint_graph_t graph) 2564 1.1 mrg { 2565 1.1 mrg int i; 2566 1.1 mrg constraint_t c; 2567 1.1 mrg 2568 1.1 mrg FOR_EACH_VEC_ELT (constraints, i, c) 2569 1.1 mrg { 2570 1.1 mrg if (c) 2571 1.1 mrg { 2572 1.1 mrg struct constraint_expr lhs = c->lhs; 2573 1.1 mrg struct constraint_expr rhs = c->rhs; 2574 1.1 mrg 2575 1.1 mrg if (lhs.type == DEREF) 2576 1.1 mrg { 2577 1.1 mrg insert_into_complex (graph, lhs.var, c); 2578 1.1 mrg } 2579 1.1 mrg else if (rhs.type == DEREF) 2580 1.1 mrg { 2581 1.1 mrg if (!(get_varinfo (lhs.var)->is_special_var)) 2582 1.1 mrg insert_into_complex (graph, rhs.var, c); 2583 1.1 mrg } 2584 1.1 mrg else if (rhs.type != ADDRESSOF && lhs.var > anything_id 2585 1.1 mrg && (lhs.offset != 0 || rhs.offset != 0)) 2586 1.1 mrg { 2587 1.1 mrg insert_into_complex (graph, rhs.var, c); 2588 1.1 mrg } 2589 1.1 mrg } 2590 1.1 mrg } 2591 1.1 mrg } 2592 1.1 mrg 2593 1.1 mrg 2594 1.1 mrg /* Optimize and rewrite complex constraints while performing 2595 1.1 mrg collapsing of equivalent nodes. SI is the SCC_INFO that is the 2596 1.1 mrg result of perform_variable_substitution. */ 2597 1.1 mrg 2598 1.1 mrg static void 2599 1.1 mrg rewrite_constraints (constraint_graph_t graph, 2600 1.1 mrg class scc_info *si) 2601 1.1 mrg { 2602 1.1 mrg int i; 2603 1.1 mrg constraint_t c; 2604 1.1 mrg 2605 1.1 mrg if (flag_checking) 2606 1.1 mrg { 2607 1.1 mrg for (unsigned int j = 0; j < graph->size; j++) 2608 1.1 mrg gcc_assert (find (j) == j); 2609 1.1 mrg } 2610 1.1 mrg 2611 1.1 mrg FOR_EACH_VEC_ELT (constraints, i, c) 2612 1.1 mrg { 2613 1.1 mrg struct constraint_expr lhs = c->lhs; 2614 1.1 mrg struct constraint_expr rhs = c->rhs; 2615 1.1 mrg unsigned int lhsvar = find (lhs.var); 2616 1.1 mrg unsigned int rhsvar = find (rhs.var); 2617 1.1 mrg unsigned int lhsnode, rhsnode; 2618 1.1 mrg unsigned int lhslabel, rhslabel; 2619 1.1 mrg 2620 1.1 mrg lhsnode = si->node_mapping[lhsvar]; 2621 1.1 mrg rhsnode = si->node_mapping[rhsvar]; 2622 1.1 mrg lhslabel = graph->pointer_label[lhsnode]; 2623 1.1 mrg rhslabel = graph->pointer_label[rhsnode]; 2624 1.1 mrg 2625 1.1 mrg /* See if it is really a non-pointer variable, and if so, ignore 2626 1.1 mrg the constraint. */ 2627 1.1 mrg if (lhslabel == 0) 2628 1.1 mrg { 2629 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 2630 1.1 mrg { 2631 1.1 mrg 2632 1.1 mrg fprintf (dump_file, "%s is a non-pointer variable, " 2633 1.1 mrg "ignoring constraint:", 2634 1.1 mrg get_varinfo (lhs.var)->name); 2635 1.1 mrg dump_constraint (dump_file, c); 2636 1.1 mrg fprintf (dump_file, "\n"); 2637 1.1 mrg } 2638 1.1 mrg constraints[i] = NULL; 2639 1.1 mrg continue; 2640 1.1 mrg } 2641 1.1 mrg 2642 1.1 mrg if (rhslabel == 0) 2643 1.1 mrg { 2644 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 2645 1.1 mrg { 2646 1.1 mrg 2647 1.1 mrg fprintf (dump_file, "%s is a non-pointer variable, " 2648 1.1 mrg "ignoring constraint:", 2649 1.1 mrg get_varinfo (rhs.var)->name); 2650 1.1 mrg dump_constraint (dump_file, c); 2651 1.1 mrg fprintf (dump_file, "\n"); 2652 1.1 mrg } 2653 1.1 mrg constraints[i] = NULL; 2654 1.1 mrg continue; 2655 1.1 mrg } 2656 1.1 mrg 2657 1.1 mrg lhsvar = find_equivalent_node (graph, lhsvar, lhslabel); 2658 1.1 mrg rhsvar = find_equivalent_node (graph, rhsvar, rhslabel); 2659 1.1 mrg c->lhs.var = lhsvar; 2660 1.1 mrg c->rhs.var = rhsvar; 2661 1.1 mrg } 2662 1.1 mrg } 2663 1.1 mrg 2664 1.1 mrg /* Eliminate indirect cycles involving NODE. Return true if NODE was 2665 1.1 mrg part of an SCC, false otherwise. */ 2666 1.1 mrg 2667 1.1 mrg static bool 2668 1.1 mrg eliminate_indirect_cycles (unsigned int node) 2669 1.1 mrg { 2670 1.1 mrg if (graph->indirect_cycles[node] != -1 2671 1.1 mrg && !bitmap_empty_p (get_varinfo (node)->solution)) 2672 1.1 mrg { 2673 1.1 mrg unsigned int i; 2674 1.1 mrg auto_vec<unsigned> queue; 2675 1.1 mrg int queuepos; 2676 1.1 mrg unsigned int to = find (graph->indirect_cycles[node]); 2677 1.1 mrg bitmap_iterator bi; 2678 1.1 mrg 2679 1.1 mrg /* We can't touch the solution set and call unify_nodes 2680 1.1 mrg at the same time, because unify_nodes is going to do 2681 1.1 mrg bitmap unions into it. */ 2682 1.1 mrg 2683 1.1 mrg EXECUTE_IF_SET_IN_BITMAP (get_varinfo (node)->solution, 0, i, bi) 2684 1.1 mrg { 2685 1.1 mrg if (find (i) == i && i != to) 2686 1.1 mrg { 2687 1.1 mrg if (unite (to, i)) 2688 1.1 mrg queue.safe_push (i); 2689 1.1 mrg } 2690 1.1 mrg } 2691 1.1 mrg 2692 1.1 mrg for (queuepos = 0; 2693 1.1 mrg queue.iterate (queuepos, &i); 2694 1.1 mrg queuepos++) 2695 1.1 mrg { 2696 1.1 mrg unify_nodes (graph, to, i, true); 2697 1.1 mrg } 2698 1.1 mrg return true; 2699 1.1 mrg } 2700 1.1 mrg return false; 2701 1.1 mrg } 2702 1.1 mrg 2703 1.1 mrg /* Solve the constraint graph GRAPH using our worklist solver. 2704 1.1 mrg This is based on the PW* family of solvers from the "Efficient Field 2705 1.1 mrg Sensitive Pointer Analysis for C" paper. 2706 1.1 mrg It works by iterating over all the graph nodes, processing the complex 2707 1.1 mrg constraints and propagating the copy constraints, until everything stops 2708 1.1 mrg changed. This corresponds to steps 6-8 in the solving list given above. */ 2709 1.1 mrg 2710 1.1 mrg static void 2711 1.1 mrg solve_graph (constraint_graph_t graph) 2712 1.1 mrg { 2713 1.1 mrg unsigned int size = graph->size; 2714 1.1 mrg unsigned int i; 2715 1.1 mrg bitmap pts; 2716 1.1 mrg 2717 1.1 mrg changed = BITMAP_ALLOC (NULL); 2718 1.1 mrg 2719 1.1 mrg /* Mark all initial non-collapsed nodes as changed. */ 2720 1.1 mrg for (i = 1; i < size; i++) 2721 1.1 mrg { 2722 1.1 mrg varinfo_t ivi = get_varinfo (i); 2723 1.1 mrg if (find (i) == i && !bitmap_empty_p (ivi->solution) 2724 1.1 mrg && ((graph->succs[i] && !bitmap_empty_p (graph->succs[i])) 2725 1.1 mrg || graph->complex[i].length () > 0)) 2726 1.1 mrg bitmap_set_bit (changed, i); 2727 1.1 mrg } 2728 1.1 mrg 2729 1.1 mrg /* Allocate a bitmap to be used to store the changed bits. */ 2730 1.1 mrg pts = BITMAP_ALLOC (&pta_obstack); 2731 1.1 mrg 2732 1.1 mrg while (!bitmap_empty_p (changed)) 2733 1.1 mrg { 2734 1.1 mrg unsigned int i; 2735 1.1 mrg stats.iterations++; 2736 1.1 mrg 2737 1.1 mrg bitmap_obstack_initialize (&iteration_obstack); 2738 1.1 mrg 2739 1.1 mrg auto_vec<unsigned> topo_order = compute_topo_order (graph); 2740 1.1 mrg while (topo_order.length () != 0) 2741 1.1 mrg { 2742 1.1 mrg i = topo_order.pop (); 2743 1.1 mrg 2744 1.1 mrg /* If this variable is not a representative, skip it. */ 2745 1.1 mrg if (find (i) != i) 2746 1.1 mrg continue; 2747 1.1 mrg 2748 1.1 mrg /* In certain indirect cycle cases, we may merge this 2749 1.1 mrg variable to another. */ 2750 1.1 mrg if (eliminate_indirect_cycles (i) && find (i) != i) 2751 1.1 mrg continue; 2752 1.1 mrg 2753 1.1 mrg /* If the node has changed, we need to process the 2754 1.1 mrg complex constraints and outgoing edges again. */ 2755 1.1 mrg if (bitmap_clear_bit (changed, i)) 2756 1.1 mrg { 2757 1.1 mrg unsigned int j; 2758 1.1 mrg constraint_t c; 2759 1.1 mrg bitmap solution; 2760 1.1 mrg vec<constraint_t> complex = graph->complex[i]; 2761 1.1 mrg varinfo_t vi = get_varinfo (i); 2762 1.1 mrg bool solution_empty; 2763 1.1 mrg 2764 1.1 mrg /* Compute the changed set of solution bits. If anything 2765 1.1 mrg is in the solution just propagate that. */ 2766 1.1 mrg if (bitmap_bit_p (vi->solution, anything_id)) 2767 1.1 mrg { 2768 1.1 mrg /* If anything is also in the old solution there is 2769 1.1 mrg nothing to do. 2770 1.1 mrg ??? But we shouldn't ended up with "changed" set ... */ 2771 1.1 mrg if (vi->oldsolution 2772 1.1 mrg && bitmap_bit_p (vi->oldsolution, anything_id)) 2773 1.1 mrg continue; 2774 1.1 mrg bitmap_copy (pts, get_varinfo (find (anything_id))->solution); 2775 1.1 mrg } 2776 1.1 mrg else if (vi->oldsolution) 2777 1.1 mrg bitmap_and_compl (pts, vi->solution, vi->oldsolution); 2778 1.1 mrg else 2779 1.1 mrg bitmap_copy (pts, vi->solution); 2780 1.1 mrg 2781 1.1 mrg if (bitmap_empty_p (pts)) 2782 1.1 mrg continue; 2783 1.1 mrg 2784 1.1 mrg if (vi->oldsolution) 2785 1.1 mrg bitmap_ior_into (vi->oldsolution, pts); 2786 1.1 mrg else 2787 1.1 mrg { 2788 1.1 mrg vi->oldsolution = BITMAP_ALLOC (&oldpta_obstack); 2789 1.1 mrg bitmap_copy (vi->oldsolution, pts); 2790 1.1 mrg } 2791 1.1 mrg 2792 1.1 mrg solution = vi->solution; 2793 1.1 mrg solution_empty = bitmap_empty_p (solution); 2794 1.1 mrg 2795 1.1 mrg /* Process the complex constraints */ 2796 1.1 mrg bitmap expanded_pts = NULL; 2797 1.1 mrg FOR_EACH_VEC_ELT (complex, j, c) 2798 1.1 mrg { 2799 1.1 mrg /* XXX: This is going to unsort the constraints in 2800 1.1 mrg some cases, which will occasionally add duplicate 2801 1.1 mrg constraints during unification. This does not 2802 1.1 mrg affect correctness. */ 2803 1.1 mrg c->lhs.var = find (c->lhs.var); 2804 1.1 mrg c->rhs.var = find (c->rhs.var); 2805 1.1 mrg 2806 1.1 mrg /* The only complex constraint that can change our 2807 1.1 mrg solution to non-empty, given an empty solution, 2808 1.1 mrg is a constraint where the lhs side is receiving 2809 1.1 mrg some set from elsewhere. */ 2810 1.1 mrg if (!solution_empty || c->lhs.type != DEREF) 2811 1.1 mrg do_complex_constraint (graph, c, pts, &expanded_pts); 2812 1.1 mrg } 2813 1.1 mrg BITMAP_FREE (expanded_pts); 2814 1.1 mrg 2815 1.1 mrg solution_empty = bitmap_empty_p (solution); 2816 1.1 mrg 2817 1.1 mrg if (!solution_empty) 2818 1.1 mrg { 2819 1.1 mrg bitmap_iterator bi; 2820 1.1 mrg unsigned eff_escaped_id = find (escaped_id); 2821 1.1 mrg 2822 1.1 mrg /* Propagate solution to all successors. */ 2823 1.1 mrg unsigned to_remove = ~0U; 2824 1.1 mrg EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[i], 2825 1.1 mrg 0, j, bi) 2826 1.1 mrg { 2827 1.1 mrg if (to_remove != ~0U) 2828 1.1 mrg { 2829 1.1 mrg bitmap_clear_bit (graph->succs[i], to_remove); 2830 1.1 mrg to_remove = ~0U; 2831 1.1 mrg } 2832 1.1 mrg unsigned int to = find (j); 2833 1.1 mrg if (to != j) 2834 1.1 mrg { 2835 1.1 mrg /* Update the succ graph, avoiding duplicate 2836 1.1 mrg work. */ 2837 1.1 mrg to_remove = j; 2838 1.1 mrg if (! bitmap_set_bit (graph->succs[i], to)) 2839 1.1 mrg continue; 2840 1.1 mrg /* We eventually end up processing 'to' twice 2841 1.1 mrg as it is undefined whether bitmap iteration 2842 1.1 mrg iterates over bits set during iteration. 2843 1.1 mrg Play safe instead of doing tricks. */ 2844 1.1 mrg } 2845 1.1 mrg /* Don't try to propagate to ourselves. */ 2846 1.1 mrg if (to == i) 2847 1.1 mrg continue; 2848 1.1 mrg 2849 1.1 mrg bitmap tmp = get_varinfo (to)->solution; 2850 1.1 mrg bool flag = false; 2851 1.1 mrg 2852 1.1 mrg /* If we propagate from ESCAPED use ESCAPED as 2853 1.1 mrg placeholder. */ 2854 1.1 mrg if (i == eff_escaped_id) 2855 1.1 mrg flag = bitmap_set_bit (tmp, escaped_id); 2856 1.1 mrg else 2857 1.1 mrg flag = bitmap_ior_into (tmp, pts); 2858 1.1 mrg 2859 1.1 mrg if (flag) 2860 1.1 mrg bitmap_set_bit (changed, to); 2861 1.1 mrg } 2862 1.1 mrg if (to_remove != ~0U) 2863 1.1 mrg bitmap_clear_bit (graph->succs[i], to_remove); 2864 1.1 mrg } 2865 1.1 mrg } 2866 1.1 mrg } 2867 1.1 mrg bitmap_obstack_release (&iteration_obstack); 2868 1.1 mrg } 2869 1.1 mrg 2870 1.1 mrg BITMAP_FREE (pts); 2871 1.1 mrg BITMAP_FREE (changed); 2872 1.1 mrg bitmap_obstack_release (&oldpta_obstack); 2873 1.1 mrg } 2874 1.1 mrg 2875 1.1 mrg /* Map from trees to variable infos. */ 2876 1.1 mrg static hash_map<tree, varinfo_t> *vi_for_tree; 2877 1.1 mrg 2878 1.1 mrg 2879 1.1 mrg /* Insert ID as the variable id for tree T in the vi_for_tree map. */ 2880 1.1 mrg 2881 1.1 mrg static void 2882 1.1 mrg insert_vi_for_tree (tree t, varinfo_t vi) 2883 1.1 mrg { 2884 1.1 mrg gcc_assert (vi); 2885 1.1 mrg bool existed = vi_for_tree->put (t, vi); 2886 1.1 mrg gcc_assert (!existed); 2887 1.1 mrg } 2888 1.1 mrg 2889 1.1 mrg /* Find the variable info for tree T in VI_FOR_TREE. If T does not 2890 1.1 mrg exist in the map, return NULL, otherwise, return the varinfo we found. */ 2891 1.1 mrg 2892 1.1 mrg static varinfo_t 2893 1.1 mrg lookup_vi_for_tree (tree t) 2894 1.1 mrg { 2895 1.1 mrg varinfo_t *slot = vi_for_tree->get (t); 2896 1.1 mrg if (slot == NULL) 2897 1.1 mrg return NULL; 2898 1.1 mrg 2899 1.1 mrg return *slot; 2900 1.1 mrg } 2901 1.1 mrg 2902 1.1 mrg /* Return a printable name for DECL */ 2903 1.1 mrg 2904 1.1 mrg static const char * 2905 1.1 mrg alias_get_name (tree decl) 2906 1.1 mrg { 2907 1.1 mrg const char *res = "NULL"; 2908 1.1 mrg if (dump_file) 2909 1.1 mrg { 2910 1.1 mrg char *temp = NULL; 2911 1.1 mrg if (TREE_CODE (decl) == SSA_NAME) 2912 1.1 mrg { 2913 1.1 mrg res = get_name (decl); 2914 1.1 mrg temp = xasprintf ("%s_%u", res ? res : "", SSA_NAME_VERSION (decl)); 2915 1.1 mrg } 2916 1.1 mrg else if (HAS_DECL_ASSEMBLER_NAME_P (decl) 2917 1.1 mrg && DECL_ASSEMBLER_NAME_SET_P (decl)) 2918 1.1 mrg res = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME_RAW (decl)); 2919 1.1 mrg else if (DECL_P (decl)) 2920 1.1 mrg { 2921 1.1 mrg res = get_name (decl); 2922 1.1 mrg if (!res) 2923 1.1 mrg temp = xasprintf ("D.%u", DECL_UID (decl)); 2924 1.1 mrg } 2925 1.1 mrg 2926 1.1 mrg if (temp) 2927 1.1 mrg { 2928 1.1 mrg res = ggc_strdup (temp); 2929 1.1 mrg free (temp); 2930 1.1 mrg } 2931 1.1 mrg } 2932 1.1 mrg 2933 1.1 mrg return res; 2934 1.1 mrg } 2935 1.1 mrg 2936 1.1 mrg /* Find the variable id for tree T in the map. 2937 1.1 mrg If T doesn't exist in the map, create an entry for it and return it. */ 2938 1.1 mrg 2939 1.1 mrg static varinfo_t 2940 1.1 mrg get_vi_for_tree (tree t) 2941 1.1 mrg { 2942 1.1 mrg varinfo_t *slot = vi_for_tree->get (t); 2943 1.1 mrg if (slot == NULL) 2944 1.1 mrg { 2945 1.1 mrg unsigned int id = create_variable_info_for (t, alias_get_name (t), false); 2946 1.1 mrg return get_varinfo (id); 2947 1.1 mrg } 2948 1.1 mrg 2949 1.1 mrg return *slot; 2950 1.1 mrg } 2951 1.1 mrg 2952 1.1 mrg /* Get a scalar constraint expression for a new temporary variable. */ 2953 1.1 mrg 2954 1.1 mrg static struct constraint_expr 2955 1.1 mrg new_scalar_tmp_constraint_exp (const char *name, bool add_id) 2956 1.1 mrg { 2957 1.1 mrg struct constraint_expr tmp; 2958 1.1 mrg varinfo_t vi; 2959 1.1 mrg 2960 1.1 mrg vi = new_var_info (NULL_TREE, name, add_id); 2961 1.1 mrg vi->offset = 0; 2962 1.1 mrg vi->size = -1; 2963 1.1 mrg vi->fullsize = -1; 2964 1.1 mrg vi->is_full_var = 1; 2965 1.1 mrg vi->is_reg_var = 1; 2966 1.1 mrg 2967 1.1 mrg tmp.var = vi->id; 2968 1.1 mrg tmp.type = SCALAR; 2969 1.1 mrg tmp.offset = 0; 2970 1.1 mrg 2971 1.1 mrg return tmp; 2972 1.1 mrg } 2973 1.1 mrg 2974 1.1 mrg /* Get a constraint expression vector from an SSA_VAR_P node. 2975 1.1 mrg If address_p is true, the result will be taken its address of. */ 2976 1.1 mrg 2977 1.1 mrg static void 2978 1.1 mrg get_constraint_for_ssa_var (tree t, vec<ce_s> *results, bool address_p) 2979 1.1 mrg { 2980 1.1 mrg struct constraint_expr cexpr; 2981 1.1 mrg varinfo_t vi; 2982 1.1 mrg 2983 1.1 mrg /* We allow FUNCTION_DECLs here even though it doesn't make much sense. */ 2984 1.1 mrg gcc_assert (TREE_CODE (t) == SSA_NAME || DECL_P (t)); 2985 1.1 mrg 2986 1.1 mrg if (TREE_CODE (t) == SSA_NAME 2987 1.1 mrg && SSA_NAME_IS_DEFAULT_DEF (t)) 2988 1.1 mrg { 2989 1.1 mrg /* For parameters, get at the points-to set for the actual parm 2990 1.1 mrg decl. */ 2991 1.1 mrg if (TREE_CODE (SSA_NAME_VAR (t)) == PARM_DECL 2992 1.1 mrg || TREE_CODE (SSA_NAME_VAR (t)) == RESULT_DECL) 2993 1.1 mrg { 2994 1.1 mrg get_constraint_for_ssa_var (SSA_NAME_VAR (t), results, address_p); 2995 1.1 mrg return; 2996 1.1 mrg } 2997 1.1 mrg /* For undefined SSA names return nothing. */ 2998 1.1 mrg else if (!ssa_defined_default_def_p (t)) 2999 1.1 mrg { 3000 1.1 mrg cexpr.var = nothing_id; 3001 1.1 mrg cexpr.type = SCALAR; 3002 1.1 mrg cexpr.offset = 0; 3003 1.1 mrg results->safe_push (cexpr); 3004 1.1 mrg return; 3005 1.1 mrg } 3006 1.1 mrg } 3007 1.1 mrg 3008 1.1 mrg /* For global variables resort to the alias target. */ 3009 1.1 mrg if (VAR_P (t) && (TREE_STATIC (t) || DECL_EXTERNAL (t))) 3010 1.1 mrg { 3011 1.1 mrg varpool_node *node = varpool_node::get (t); 3012 1.1 mrg if (node && node->alias && node->analyzed) 3013 1.1 mrg { 3014 1.1 mrg node = node->ultimate_alias_target (); 3015 1.1 mrg /* Canonicalize the PT uid of all aliases to the ultimate target. 3016 1.1 mrg ??? Hopefully the set of aliases can't change in a way that 3017 1.1 mrg changes the ultimate alias target. */ 3018 1.1 mrg gcc_assert ((! DECL_PT_UID_SET_P (node->decl) 3019 1.1 mrg || DECL_PT_UID (node->decl) == DECL_UID (node->decl)) 3020 1.1 mrg && (! DECL_PT_UID_SET_P (t) 3021 1.1 mrg || DECL_PT_UID (t) == DECL_UID (node->decl))); 3022 1.1 mrg DECL_PT_UID (t) = DECL_UID (node->decl); 3023 1.1 mrg t = node->decl; 3024 1.1 mrg } 3025 1.1 mrg 3026 1.1 mrg /* If this is decl may bind to NULL note that. */ 3027 1.1 mrg if (address_p 3028 1.1 mrg && (! node || ! node->nonzero_address ())) 3029 1.1 mrg { 3030 1.1 mrg cexpr.var = nothing_id; 3031 1.1 mrg cexpr.type = SCALAR; 3032 1.1 mrg cexpr.offset = 0; 3033 1.1 mrg results->safe_push (cexpr); 3034 1.1 mrg } 3035 1.1 mrg } 3036 1.1 mrg 3037 1.1 mrg vi = get_vi_for_tree (t); 3038 1.1 mrg cexpr.var = vi->id; 3039 1.1 mrg cexpr.type = SCALAR; 3040 1.1 mrg cexpr.offset = 0; 3041 1.1 mrg 3042 1.1 mrg /* If we are not taking the address of the constraint expr, add all 3043 1.1 mrg sub-fiels of the variable as well. */ 3044 1.1 mrg if (!address_p 3045 1.1 mrg && !vi->is_full_var) 3046 1.1 mrg { 3047 1.1 mrg for (; vi; vi = vi_next (vi)) 3048 1.1 mrg { 3049 1.1 mrg cexpr.var = vi->id; 3050 1.1 mrg results->safe_push (cexpr); 3051 1.1 mrg } 3052 1.1 mrg return; 3053 1.1 mrg } 3054 1.1 mrg 3055 1.1 mrg results->safe_push (cexpr); 3056 1.1 mrg } 3057 1.1 mrg 3058 1.1 mrg /* Process constraint T, performing various simplifications and then 3059 1.1 mrg adding it to our list of overall constraints. */ 3060 1.1 mrg 3061 1.1 mrg static void 3062 1.1 mrg process_constraint (constraint_t t) 3063 1.1 mrg { 3064 1.1 mrg struct constraint_expr rhs = t->rhs; 3065 1.1 mrg struct constraint_expr lhs = t->lhs; 3066 1.1 mrg 3067 1.1 mrg gcc_assert (rhs.var < varmap.length ()); 3068 1.1 mrg gcc_assert (lhs.var < varmap.length ()); 3069 1.1 mrg 3070 1.1 mrg /* If we didn't get any useful constraint from the lhs we get 3071 1.1 mrg &ANYTHING as fallback from get_constraint_for. Deal with 3072 1.1 mrg it here by turning it into *ANYTHING. */ 3073 1.1 mrg if (lhs.type == ADDRESSOF 3074 1.1 mrg && lhs.var == anything_id) 3075 1.1 mrg lhs.type = DEREF; 3076 1.1 mrg 3077 1.1 mrg /* ADDRESSOF on the lhs is invalid. */ 3078 1.1 mrg gcc_assert (lhs.type != ADDRESSOF); 3079 1.1 mrg 3080 1.1 mrg /* We shouldn't add constraints from things that cannot have pointers. 3081 1.1 mrg It's not completely trivial to avoid in the callers, so do it here. */ 3082 1.1 mrg if (rhs.type != ADDRESSOF 3083 1.1 mrg && !get_varinfo (rhs.var)->may_have_pointers) 3084 1.1 mrg return; 3085 1.1 mrg 3086 1.1 mrg /* Likewise adding to the solution of a non-pointer var isn't useful. */ 3087 1.1 mrg if (!get_varinfo (lhs.var)->may_have_pointers) 3088 1.1 mrg return; 3089 1.1 mrg 3090 1.1 mrg /* This can happen in our IR with things like n->a = *p */ 3091 1.1 mrg if (rhs.type == DEREF && lhs.type == DEREF && rhs.var != anything_id) 3092 1.1 mrg { 3093 1.1 mrg /* Split into tmp = *rhs, *lhs = tmp */ 3094 1.1 mrg struct constraint_expr tmplhs; 3095 1.1 mrg tmplhs = new_scalar_tmp_constraint_exp ("doubledereftmp", true); 3096 1.1 mrg process_constraint (new_constraint (tmplhs, rhs)); 3097 1.1 mrg process_constraint (new_constraint (lhs, tmplhs)); 3098 1.1 mrg } 3099 1.1 mrg else if ((rhs.type != SCALAR || rhs.offset != 0) && lhs.type == DEREF) 3100 1.1 mrg { 3101 1.1 mrg /* Split into tmp = &rhs, *lhs = tmp */ 3102 1.1 mrg struct constraint_expr tmplhs; 3103 1.1 mrg tmplhs = new_scalar_tmp_constraint_exp ("derefaddrtmp", true); 3104 1.1 mrg process_constraint (new_constraint (tmplhs, rhs)); 3105 1.1 mrg process_constraint (new_constraint (lhs, tmplhs)); 3106 1.1 mrg } 3107 1.1 mrg else 3108 1.1 mrg { 3109 1.1 mrg gcc_assert (rhs.type != ADDRESSOF || rhs.offset == 0); 3110 1.1 mrg if (rhs.type == ADDRESSOF) 3111 1.1 mrg get_varinfo (get_varinfo (rhs.var)->head)->address_taken = true; 3112 1.1 mrg constraints.safe_push (t); 3113 1.1 mrg } 3114 1.1 mrg } 3115 1.1 mrg 3116 1.1 mrg 3117 1.1 mrg /* Return the position, in bits, of FIELD_DECL from the beginning of its 3118 1.1 mrg structure. */ 3119 1.1 mrg 3120 1.1 mrg static HOST_WIDE_INT 3121 1.1 mrg bitpos_of_field (const tree fdecl) 3122 1.1 mrg { 3123 1.1 mrg if (!tree_fits_shwi_p (DECL_FIELD_OFFSET (fdecl)) 3124 1.1 mrg || !tree_fits_shwi_p (DECL_FIELD_BIT_OFFSET (fdecl))) 3125 1.1 mrg return -1; 3126 1.1 mrg 3127 1.1 mrg return (tree_to_shwi (DECL_FIELD_OFFSET (fdecl)) * BITS_PER_UNIT 3128 1.1 mrg + tree_to_shwi (DECL_FIELD_BIT_OFFSET (fdecl))); 3129 1.1 mrg } 3130 1.1 mrg 3131 1.1 mrg 3132 1.1 mrg /* Get constraint expressions for offsetting PTR by OFFSET. Stores the 3133 1.1 mrg resulting constraint expressions in *RESULTS. */ 3134 1.1 mrg 3135 1.1 mrg static void 3136 1.1 mrg get_constraint_for_ptr_offset (tree ptr, tree offset, 3137 1.1 mrg vec<ce_s> *results) 3138 1.1 mrg { 3139 1.1 mrg struct constraint_expr c; 3140 1.1 mrg unsigned int j, n; 3141 1.1 mrg HOST_WIDE_INT rhsoffset; 3142 1.1 mrg 3143 1.1 mrg /* If we do not do field-sensitive PTA adding offsets to pointers 3144 1.1 mrg does not change the points-to solution. */ 3145 1.1 mrg if (!use_field_sensitive) 3146 1.1 mrg { 3147 1.1 mrg get_constraint_for_rhs (ptr, results); 3148 1.1 mrg return; 3149 1.1 mrg } 3150 1.1 mrg 3151 1.1 mrg /* If the offset is not a non-negative integer constant that fits 3152 1.1 mrg in a HOST_WIDE_INT, we have to fall back to a conservative 3153 1.1 mrg solution which includes all sub-fields of all pointed-to 3154 1.1 mrg variables of ptr. */ 3155 1.1 mrg if (offset == NULL_TREE 3156 1.1 mrg || TREE_CODE (offset) != INTEGER_CST) 3157 1.1 mrg rhsoffset = UNKNOWN_OFFSET; 3158 1.1 mrg else 3159 1.1 mrg { 3160 1.1 mrg /* Sign-extend the offset. */ 3161 1.1 mrg offset_int soffset = offset_int::from (wi::to_wide (offset), SIGNED); 3162 1.1 mrg if (!wi::fits_shwi_p (soffset)) 3163 1.1 mrg rhsoffset = UNKNOWN_OFFSET; 3164 1.1 mrg else 3165 1.1 mrg { 3166 1.1 mrg /* Make sure the bit-offset also fits. */ 3167 1.1 mrg HOST_WIDE_INT rhsunitoffset = soffset.to_shwi (); 3168 1.1 mrg rhsoffset = rhsunitoffset * (unsigned HOST_WIDE_INT) BITS_PER_UNIT; 3169 1.1 mrg if (rhsunitoffset != rhsoffset / BITS_PER_UNIT) 3170 1.1 mrg rhsoffset = UNKNOWN_OFFSET; 3171 1.1 mrg } 3172 1.1 mrg } 3173 1.1 mrg 3174 1.1 mrg get_constraint_for_rhs (ptr, results); 3175 1.1 mrg if (rhsoffset == 0) 3176 1.1 mrg return; 3177 1.1 mrg 3178 1.1 mrg /* As we are eventually appending to the solution do not use 3179 1.1 mrg vec::iterate here. */ 3180 1.1 mrg n = results->length (); 3181 1.1 mrg for (j = 0; j < n; j++) 3182 1.1 mrg { 3183 1.1 mrg varinfo_t curr; 3184 1.1 mrg c = (*results)[j]; 3185 1.1 mrg curr = get_varinfo (c.var); 3186 1.1 mrg 3187 1.1 mrg if (c.type == ADDRESSOF 3188 1.1 mrg /* If this varinfo represents a full variable just use it. */ 3189 1.1 mrg && curr->is_full_var) 3190 1.1 mrg ; 3191 1.1 mrg else if (c.type == ADDRESSOF 3192 1.1 mrg /* If we do not know the offset add all subfields. */ 3193 1.1 mrg && rhsoffset == UNKNOWN_OFFSET) 3194 1.1 mrg { 3195 1.1 mrg varinfo_t temp = get_varinfo (curr->head); 3196 1.1 mrg do 3197 1.1 mrg { 3198 1.1 mrg struct constraint_expr c2; 3199 1.1 mrg c2.var = temp->id; 3200 1.1 mrg c2.type = ADDRESSOF; 3201 1.1 mrg c2.offset = 0; 3202 1.1 mrg if (c2.var != c.var) 3203 1.1 mrg results->safe_push (c2); 3204 1.1 mrg temp = vi_next (temp); 3205 1.1 mrg } 3206 1.1 mrg while (temp); 3207 1.1 mrg } 3208 1.1 mrg else if (c.type == ADDRESSOF) 3209 1.1 mrg { 3210 1.1 mrg varinfo_t temp; 3211 1.1 mrg unsigned HOST_WIDE_INT offset = curr->offset + rhsoffset; 3212 1.1 mrg 3213 1.1 mrg /* If curr->offset + rhsoffset is less than zero adjust it. */ 3214 1.1 mrg if (rhsoffset < 0 3215 1.1 mrg && curr->offset < offset) 3216 1.1 mrg offset = 0; 3217 1.1 mrg 3218 1.1 mrg /* We have to include all fields that overlap the current 3219 1.1 mrg field shifted by rhsoffset. And we include at least 3220 1.1 mrg the last or the first field of the variable to represent 3221 1.1 mrg reachability of off-bound addresses, in particular &object + 1, 3222 1.1 mrg conservatively correct. */ 3223 1.1 mrg temp = first_or_preceding_vi_for_offset (curr, offset); 3224 1.1 mrg c.var = temp->id; 3225 1.1 mrg c.offset = 0; 3226 1.1 mrg temp = vi_next (temp); 3227 1.1 mrg while (temp 3228 1.1 mrg && temp->offset < offset + curr->size) 3229 1.1 mrg { 3230 1.1 mrg struct constraint_expr c2; 3231 1.1 mrg c2.var = temp->id; 3232 1.1 mrg c2.type = ADDRESSOF; 3233 1.1 mrg c2.offset = 0; 3234 1.1 mrg results->safe_push (c2); 3235 1.1 mrg temp = vi_next (temp); 3236 1.1 mrg } 3237 1.1 mrg } 3238 1.1 mrg else if (c.type == SCALAR) 3239 1.1 mrg { 3240 1.1 mrg gcc_assert (c.offset == 0); 3241 1.1 mrg c.offset = rhsoffset; 3242 1.1 mrg } 3243 1.1 mrg else 3244 1.1 mrg /* We shouldn't get any DEREFs here. */ 3245 1.1 mrg gcc_unreachable (); 3246 1.1 mrg 3247 1.1 mrg (*results)[j] = c; 3248 1.1 mrg } 3249 1.1 mrg } 3250 1.1 mrg 3251 1.1 mrg 3252 1.1 mrg /* Given a COMPONENT_REF T, return the constraint_expr vector for it. 3253 1.1 mrg If address_p is true the result will be taken its address of. 3254 1.1 mrg If lhs_p is true then the constraint expression is assumed to be used 3255 1.1 mrg as the lhs. */ 3256 1.1 mrg 3257 1.1 mrg static void 3258 1.1 mrg get_constraint_for_component_ref (tree t, vec<ce_s> *results, 3259 1.1 mrg bool address_p, bool lhs_p) 3260 1.1 mrg { 3261 1.1 mrg tree orig_t = t; 3262 1.1 mrg poly_int64 bitsize = -1; 3263 1.1 mrg poly_int64 bitmaxsize = -1; 3264 1.1 mrg poly_int64 bitpos; 3265 1.1 mrg bool reverse; 3266 1.1 mrg tree forzero; 3267 1.1 mrg 3268 1.1 mrg /* Some people like to do cute things like take the address of 3269 1.1 mrg &0->a.b */ 3270 1.1 mrg forzero = t; 3271 1.1 mrg while (handled_component_p (forzero) 3272 1.1 mrg || INDIRECT_REF_P (forzero) 3273 1.1 mrg || TREE_CODE (forzero) == MEM_REF) 3274 1.1 mrg forzero = TREE_OPERAND (forzero, 0); 3275 1.1 mrg 3276 1.1 mrg if (CONSTANT_CLASS_P (forzero) && integer_zerop (forzero)) 3277 1.1 mrg { 3278 1.1 mrg struct constraint_expr temp; 3279 1.1 mrg 3280 1.1 mrg temp.offset = 0; 3281 1.1 mrg temp.var = integer_id; 3282 1.1 mrg temp.type = SCALAR; 3283 1.1 mrg results->safe_push (temp); 3284 1.1 mrg return; 3285 1.1 mrg } 3286 1.1 mrg 3287 1.1 mrg t = get_ref_base_and_extent (t, &bitpos, &bitsize, &bitmaxsize, &reverse); 3288 1.1 mrg 3289 1.1 mrg /* We can end up here for component references on a 3290 1.1 mrg VIEW_CONVERT_EXPR <>(&foobar) or things like a 3291 1.1 mrg BIT_FIELD_REF <&MEM[(void *)&b + 4B], ...>. So for 3292 1.1 mrg symbolic constants simply give up. */ 3293 1.1 mrg if (TREE_CODE (t) == ADDR_EXPR) 3294 1.1 mrg { 3295 1.1 mrg constraint_expr result; 3296 1.1 mrg result.type = SCALAR; 3297 1.1 mrg result.var = anything_id; 3298 1.1 mrg result.offset = 0; 3299 1.1 mrg results->safe_push (result); 3300 1.1 mrg return; 3301 1.1 mrg } 3302 1.1 mrg 3303 1.1 mrg /* Avoid creating pointer-offset constraints, so handle MEM_REF 3304 1.1 mrg offsets directly. Pretend to take the address of the base, 3305 1.1 mrg we'll take care of adding the required subset of sub-fields below. */ 3306 1.1 mrg if (TREE_CODE (t) == MEM_REF 3307 1.1 mrg && !integer_zerop (TREE_OPERAND (t, 0))) 3308 1.1 mrg { 3309 1.1 mrg poly_offset_int off = mem_ref_offset (t); 3310 1.1 mrg off <<= LOG2_BITS_PER_UNIT; 3311 1.1 mrg off += bitpos; 3312 1.1 mrg poly_int64 off_hwi; 3313 1.1 mrg if (off.to_shwi (&off_hwi)) 3314 1.1 mrg bitpos = off_hwi; 3315 1.1 mrg else 3316 1.1 mrg { 3317 1.1 mrg bitpos = 0; 3318 1.1 mrg bitmaxsize = -1; 3319 1.1 mrg } 3320 1.1 mrg get_constraint_for_1 (TREE_OPERAND (t, 0), results, false, lhs_p); 3321 1.1 mrg do_deref (results); 3322 1.1 mrg } 3323 1.1 mrg else 3324 1.1 mrg get_constraint_for_1 (t, results, true, lhs_p); 3325 1.1 mrg 3326 1.1 mrg /* Strip off nothing_id. */ 3327 1.1 mrg if (results->length () == 2) 3328 1.1 mrg { 3329 1.1 mrg gcc_assert ((*results)[0].var == nothing_id); 3330 1.1 mrg results->unordered_remove (0); 3331 1.1 mrg } 3332 1.1 mrg gcc_assert (results->length () == 1); 3333 1.1 mrg struct constraint_expr &result = results->last (); 3334 1.1 mrg 3335 1.1 mrg if (result.type == SCALAR 3336 1.1 mrg && get_varinfo (result.var)->is_full_var) 3337 1.1 mrg /* For single-field vars do not bother about the offset. */ 3338 1.1 mrg result.offset = 0; 3339 1.1 mrg else if (result.type == SCALAR) 3340 1.1 mrg { 3341 1.1 mrg /* In languages like C, you can access one past the end of an 3342 1.1 mrg array. You aren't allowed to dereference it, so we can 3343 1.1 mrg ignore this constraint. When we handle pointer subtraction, 3344 1.1 mrg we may have to do something cute here. */ 3345 1.1 mrg 3346 1.1 mrg if (maybe_lt (poly_uint64 (bitpos), get_varinfo (result.var)->fullsize) 3347 1.1 mrg && maybe_ne (bitmaxsize, 0)) 3348 1.1 mrg { 3349 1.1 mrg /* It's also not true that the constraint will actually start at the 3350 1.1 mrg right offset, it may start in some padding. We only care about 3351 1.1 mrg setting the constraint to the first actual field it touches, so 3352 1.1 mrg walk to find it. */ 3353 1.1 mrg struct constraint_expr cexpr = result; 3354 1.1 mrg varinfo_t curr; 3355 1.1 mrg results->pop (); 3356 1.1 mrg cexpr.offset = 0; 3357 1.1 mrg for (curr = get_varinfo (cexpr.var); curr; curr = vi_next (curr)) 3358 1.1 mrg { 3359 1.1 mrg if (ranges_maybe_overlap_p (poly_int64 (curr->offset), 3360 1.1 mrg curr->size, bitpos, bitmaxsize)) 3361 1.1 mrg { 3362 1.1 mrg cexpr.var = curr->id; 3363 1.1 mrg results->safe_push (cexpr); 3364 1.1 mrg if (address_p) 3365 1.1 mrg break; 3366 1.1 mrg } 3367 1.1 mrg } 3368 1.1 mrg /* If we are going to take the address of this field then 3369 1.1 mrg to be able to compute reachability correctly add at least 3370 1.1 mrg the last field of the variable. */ 3371 1.1 mrg if (address_p && results->length () == 0) 3372 1.1 mrg { 3373 1.1 mrg curr = get_varinfo (cexpr.var); 3374 1.1 mrg while (curr->next != 0) 3375 1.1 mrg curr = vi_next (curr); 3376 1.1 mrg cexpr.var = curr->id; 3377 1.1 mrg results->safe_push (cexpr); 3378 1.1 mrg } 3379 1.1 mrg else if (results->length () == 0) 3380 1.1 mrg /* Assert that we found *some* field there. The user couldn't be 3381 1.1 mrg accessing *only* padding. */ 3382 1.1 mrg /* Still the user could access one past the end of an array 3383 1.1 mrg embedded in a struct resulting in accessing *only* padding. */ 3384 1.1 mrg /* Or accessing only padding via type-punning to a type 3385 1.1 mrg that has a filed just in padding space. */ 3386 1.1 mrg { 3387 1.1 mrg cexpr.type = SCALAR; 3388 1.1 mrg cexpr.var = anything_id; 3389 1.1 mrg cexpr.offset = 0; 3390 1.1 mrg results->safe_push (cexpr); 3391 1.1 mrg } 3392 1.1 mrg } 3393 1.1 mrg else if (known_eq (bitmaxsize, 0)) 3394 1.1 mrg { 3395 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 3396 1.1 mrg fprintf (dump_file, "Access to zero-sized part of variable, " 3397 1.1 mrg "ignoring\n"); 3398 1.1 mrg } 3399 1.1 mrg else 3400 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 3401 1.1 mrg fprintf (dump_file, "Access to past the end of variable, ignoring\n"); 3402 1.1 mrg } 3403 1.1 mrg else if (result.type == DEREF) 3404 1.1 mrg { 3405 1.1 mrg /* If we do not know exactly where the access goes say so. Note 3406 1.1 mrg that only for non-structure accesses we know that we access 3407 1.1 mrg at most one subfiled of any variable. */ 3408 1.1 mrg HOST_WIDE_INT const_bitpos; 3409 1.1 mrg if (!bitpos.is_constant (&const_bitpos) 3410 1.1 mrg || const_bitpos == -1 3411 1.1 mrg || maybe_ne (bitsize, bitmaxsize) 3412 1.1 mrg || AGGREGATE_TYPE_P (TREE_TYPE (orig_t)) 3413 1.1 mrg || result.offset == UNKNOWN_OFFSET) 3414 1.1 mrg result.offset = UNKNOWN_OFFSET; 3415 1.1 mrg else 3416 1.1 mrg result.offset += const_bitpos; 3417 1.1 mrg } 3418 1.1 mrg else if (result.type == ADDRESSOF) 3419 1.1 mrg { 3420 1.1 mrg /* We can end up here for component references on constants like 3421 1.1 mrg VIEW_CONVERT_EXPR <>({ 0, 1, 2, 3 })[i]. */ 3422 1.1 mrg result.type = SCALAR; 3423 1.1 mrg result.var = anything_id; 3424 1.1 mrg result.offset = 0; 3425 1.1 mrg } 3426 1.1 mrg else 3427 1.1 mrg gcc_unreachable (); 3428 1.1 mrg } 3429 1.1 mrg 3430 1.1 mrg 3431 1.1 mrg /* Dereference the constraint expression CONS, and return the result. 3432 1.1 mrg DEREF (ADDRESSOF) = SCALAR 3433 1.1 mrg DEREF (SCALAR) = DEREF 3434 1.1 mrg DEREF (DEREF) = (temp = DEREF1; result = DEREF(temp)) 3435 1.1 mrg This is needed so that we can handle dereferencing DEREF constraints. */ 3436 1.1 mrg 3437 1.1 mrg static void 3438 1.1 mrg do_deref (vec<ce_s> *constraints) 3439 1.1 mrg { 3440 1.1 mrg struct constraint_expr *c; 3441 1.1 mrg unsigned int i = 0; 3442 1.1 mrg 3443 1.1 mrg FOR_EACH_VEC_ELT (*constraints, i, c) 3444 1.1 mrg { 3445 1.1 mrg if (c->type == SCALAR) 3446 1.1 mrg c->type = DEREF; 3447 1.1 mrg else if (c->type == ADDRESSOF) 3448 1.1 mrg c->type = SCALAR; 3449 1.1 mrg else if (c->type == DEREF) 3450 1.1 mrg { 3451 1.1 mrg struct constraint_expr tmplhs; 3452 1.1 mrg tmplhs = new_scalar_tmp_constraint_exp ("dereftmp", true); 3453 1.1 mrg process_constraint (new_constraint (tmplhs, *c)); 3454 1.1 mrg c->var = tmplhs.var; 3455 1.1 mrg } 3456 1.1 mrg else 3457 1.1 mrg gcc_unreachable (); 3458 1.1 mrg } 3459 1.1 mrg } 3460 1.1 mrg 3461 1.1 mrg /* Given a tree T, return the constraint expression for taking the 3462 1.1 mrg address of it. */ 3463 1.1 mrg 3464 1.1 mrg static void 3465 1.1 mrg get_constraint_for_address_of (tree t, vec<ce_s> *results) 3466 1.1 mrg { 3467 1.1 mrg struct constraint_expr *c; 3468 1.1 mrg unsigned int i; 3469 1.1 mrg 3470 1.1 mrg get_constraint_for_1 (t, results, true, true); 3471 1.1 mrg 3472 1.1 mrg FOR_EACH_VEC_ELT (*results, i, c) 3473 1.1 mrg { 3474 1.1 mrg if (c->type == DEREF) 3475 1.1 mrg c->type = SCALAR; 3476 1.1 mrg else 3477 1.1 mrg c->type = ADDRESSOF; 3478 1.1 mrg } 3479 1.1 mrg } 3480 1.1 mrg 3481 1.1 mrg /* Given a tree T, return the constraint expression for it. */ 3482 1.1 mrg 3483 1.1 mrg static void 3484 1.1 mrg get_constraint_for_1 (tree t, vec<ce_s> *results, bool address_p, 3485 1.1 mrg bool lhs_p) 3486 1.1 mrg { 3487 1.1 mrg struct constraint_expr temp; 3488 1.1 mrg 3489 1.1 mrg /* x = integer is all glommed to a single variable, which doesn't 3490 1.1 mrg point to anything by itself. That is, of course, unless it is an 3491 1.1 mrg integer constant being treated as a pointer, in which case, we 3492 1.1 mrg will return that this is really the addressof anything. This 3493 1.1 mrg happens below, since it will fall into the default case. The only 3494 1.1 mrg case we know something about an integer treated like a pointer is 3495 1.1 mrg when it is the NULL pointer, and then we just say it points to 3496 1.1 mrg NULL. 3497 1.1 mrg 3498 1.1 mrg Do not do that if -fno-delete-null-pointer-checks though, because 3499 1.1 mrg in that case *NULL does not fail, so it _should_ alias *anything. 3500 1.1 mrg It is not worth adding a new option or renaming the existing one, 3501 1.1 mrg since this case is relatively obscure. */ 3502 1.1 mrg if ((TREE_CODE (t) == INTEGER_CST 3503 1.1 mrg && integer_zerop (t)) 3504 1.1 mrg /* The only valid CONSTRUCTORs in gimple with pointer typed 3505 1.1 mrg elements are zero-initializer. But in IPA mode we also 3506 1.1 mrg process global initializers, so verify at least. */ 3507 1.1 mrg || (TREE_CODE (t) == CONSTRUCTOR 3508 1.1 mrg && CONSTRUCTOR_NELTS (t) == 0)) 3509 1.1 mrg { 3510 1.1 mrg if (flag_delete_null_pointer_checks) 3511 1.1 mrg temp.var = nothing_id; 3512 1.1 mrg else 3513 1.1 mrg temp.var = nonlocal_id; 3514 1.1 mrg temp.type = ADDRESSOF; 3515 1.1 mrg temp.offset = 0; 3516 1.1 mrg results->safe_push (temp); 3517 1.1 mrg return; 3518 1.1 mrg } 3519 1.1 mrg 3520 1.1 mrg /* String constants are read-only, ideally we'd have a CONST_DECL 3521 1.1 mrg for those. */ 3522 1.1 mrg if (TREE_CODE (t) == STRING_CST) 3523 1.1 mrg { 3524 1.1 mrg temp.var = string_id; 3525 1.1 mrg temp.type = SCALAR; 3526 1.1 mrg temp.offset = 0; 3527 1.1 mrg results->safe_push (temp); 3528 1.1 mrg return; 3529 1.1 mrg } 3530 1.1 mrg 3531 1.1 mrg switch (TREE_CODE_CLASS (TREE_CODE (t))) 3532 1.1 mrg { 3533 1.1 mrg case tcc_expression: 3534 1.1 mrg { 3535 1.1 mrg switch (TREE_CODE (t)) 3536 1.1 mrg { 3537 1.1 mrg case ADDR_EXPR: 3538 1.1 mrg get_constraint_for_address_of (TREE_OPERAND (t, 0), results); 3539 1.1 mrg return; 3540 1.1 mrg default:; 3541 1.1 mrg } 3542 1.1 mrg break; 3543 1.1 mrg } 3544 1.1 mrg case tcc_reference: 3545 1.1 mrg { 3546 1.1 mrg switch (TREE_CODE (t)) 3547 1.1 mrg { 3548 1.1 mrg case MEM_REF: 3549 1.1 mrg { 3550 1.1 mrg struct constraint_expr cs; 3551 1.1 mrg varinfo_t vi, curr; 3552 1.1 mrg get_constraint_for_ptr_offset (TREE_OPERAND (t, 0), 3553 1.1 mrg TREE_OPERAND (t, 1), results); 3554 1.1 mrg do_deref (results); 3555 1.1 mrg 3556 1.1 mrg /* If we are not taking the address then make sure to process 3557 1.1 mrg all subvariables we might access. */ 3558 1.1 mrg if (address_p) 3559 1.1 mrg return; 3560 1.1 mrg 3561 1.1 mrg cs = results->last (); 3562 1.1 mrg if (cs.type == DEREF 3563 1.1 mrg && type_can_have_subvars (TREE_TYPE (t))) 3564 1.1 mrg { 3565 1.1 mrg /* For dereferences this means we have to defer it 3566 1.1 mrg to solving time. */ 3567 1.1 mrg results->last ().offset = UNKNOWN_OFFSET; 3568 1.1 mrg return; 3569 1.1 mrg } 3570 1.1 mrg if (cs.type != SCALAR) 3571 1.1 mrg return; 3572 1.1 mrg 3573 1.1 mrg vi = get_varinfo (cs.var); 3574 1.1 mrg curr = vi_next (vi); 3575 1.1 mrg if (!vi->is_full_var 3576 1.1 mrg && curr) 3577 1.1 mrg { 3578 1.1 mrg unsigned HOST_WIDE_INT size; 3579 1.1 mrg if (tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (t)))) 3580 1.1 mrg size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (t))); 3581 1.1 mrg else 3582 1.1 mrg size = -1; 3583 1.1 mrg for (; curr; curr = vi_next (curr)) 3584 1.1 mrg { 3585 1.1 mrg if (curr->offset - vi->offset < size) 3586 1.1 mrg { 3587 1.1 mrg cs.var = curr->id; 3588 1.1 mrg results->safe_push (cs); 3589 1.1 mrg } 3590 1.1 mrg else 3591 1.1 mrg break; 3592 1.1 mrg } 3593 1.1 mrg } 3594 1.1 mrg return; 3595 1.1 mrg } 3596 1.1 mrg case ARRAY_REF: 3597 1.1 mrg case ARRAY_RANGE_REF: 3598 1.1 mrg case COMPONENT_REF: 3599 1.1 mrg case IMAGPART_EXPR: 3600 1.1 mrg case REALPART_EXPR: 3601 1.1 mrg case BIT_FIELD_REF: 3602 1.1 mrg get_constraint_for_component_ref (t, results, address_p, lhs_p); 3603 1.1 mrg return; 3604 1.1 mrg case VIEW_CONVERT_EXPR: 3605 1.1 mrg get_constraint_for_1 (TREE_OPERAND (t, 0), results, address_p, 3606 1.1 mrg lhs_p); 3607 1.1 mrg return; 3608 1.1 mrg /* We are missing handling for TARGET_MEM_REF here. */ 3609 1.1 mrg default:; 3610 1.1 mrg } 3611 1.1 mrg break; 3612 1.1 mrg } 3613 1.1 mrg case tcc_exceptional: 3614 1.1 mrg { 3615 1.1 mrg switch (TREE_CODE (t)) 3616 1.1 mrg { 3617 1.1 mrg case SSA_NAME: 3618 1.1 mrg { 3619 1.1 mrg get_constraint_for_ssa_var (t, results, address_p); 3620 1.1 mrg return; 3621 1.1 mrg } 3622 1.1 mrg case CONSTRUCTOR: 3623 1.1 mrg { 3624 1.1 mrg unsigned int i; 3625 1.1 mrg tree val; 3626 1.1 mrg auto_vec<ce_s> tmp; 3627 1.1 mrg FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), i, val) 3628 1.1 mrg { 3629 1.1 mrg struct constraint_expr *rhsp; 3630 1.1 mrg unsigned j; 3631 1.1 mrg get_constraint_for_1 (val, &tmp, address_p, lhs_p); 3632 1.1 mrg FOR_EACH_VEC_ELT (tmp, j, rhsp) 3633 1.1 mrg results->safe_push (*rhsp); 3634 1.1 mrg tmp.truncate (0); 3635 1.1 mrg } 3636 1.1 mrg /* We do not know whether the constructor was complete, 3637 1.1 mrg so technically we have to add &NOTHING or &ANYTHING 3638 1.1 mrg like we do for an empty constructor as well. */ 3639 1.1 mrg return; 3640 1.1 mrg } 3641 1.1 mrg default:; 3642 1.1 mrg } 3643 1.1 mrg break; 3644 1.1 mrg } 3645 1.1 mrg case tcc_declaration: 3646 1.1 mrg { 3647 1.1 mrg get_constraint_for_ssa_var (t, results, address_p); 3648 1.1 mrg return; 3649 1.1 mrg } 3650 1.1 mrg case tcc_constant: 3651 1.1 mrg { 3652 1.1 mrg /* We cannot refer to automatic variables through constants. */ 3653 1.1 mrg temp.type = ADDRESSOF; 3654 1.1 mrg temp.var = nonlocal_id; 3655 1.1 mrg temp.offset = 0; 3656 1.1 mrg results->safe_push (temp); 3657 1.1 mrg return; 3658 1.1 mrg } 3659 1.1 mrg default:; 3660 1.1 mrg } 3661 1.1 mrg 3662 1.1 mrg /* The default fallback is a constraint from anything. */ 3663 1.1 mrg temp.type = ADDRESSOF; 3664 1.1 mrg temp.var = anything_id; 3665 1.1 mrg temp.offset = 0; 3666 1.1 mrg results->safe_push (temp); 3667 1.1 mrg } 3668 1.1 mrg 3669 1.1 mrg /* Given a gimple tree T, return the constraint expression vector for it. */ 3670 1.1 mrg 3671 1.1 mrg static void 3672 1.1 mrg get_constraint_for (tree t, vec<ce_s> *results) 3673 1.1 mrg { 3674 1.1 mrg gcc_assert (results->length () == 0); 3675 1.1 mrg 3676 1.1 mrg get_constraint_for_1 (t, results, false, true); 3677 1.1 mrg } 3678 1.1 mrg 3679 1.1 mrg /* Given a gimple tree T, return the constraint expression vector for it 3680 1.1 mrg to be used as the rhs of a constraint. */ 3681 1.1 mrg 3682 1.1 mrg static void 3683 1.1 mrg get_constraint_for_rhs (tree t, vec<ce_s> *results) 3684 1.1 mrg { 3685 1.1 mrg gcc_assert (results->length () == 0); 3686 1.1 mrg 3687 1.1 mrg get_constraint_for_1 (t, results, false, false); 3688 1.1 mrg } 3689 1.1 mrg 3690 1.1 mrg 3691 1.1 mrg /* Efficiently generates constraints from all entries in *RHSC to all 3692 1.1 mrg entries in *LHSC. */ 3693 1.1 mrg 3694 1.1 mrg static void 3695 1.1 mrg process_all_all_constraints (const vec<ce_s> &lhsc, 3696 1.1 mrg const vec<ce_s> &rhsc) 3697 1.1 mrg { 3698 1.1 mrg struct constraint_expr *lhsp, *rhsp; 3699 1.1 mrg unsigned i, j; 3700 1.1 mrg 3701 1.1 mrg if (lhsc.length () <= 1 || rhsc.length () <= 1) 3702 1.1 mrg { 3703 1.1 mrg FOR_EACH_VEC_ELT (lhsc, i, lhsp) 3704 1.1 mrg FOR_EACH_VEC_ELT (rhsc, j, rhsp) 3705 1.1 mrg process_constraint (new_constraint (*lhsp, *rhsp)); 3706 1.1 mrg } 3707 1.1 mrg else 3708 1.1 mrg { 3709 1.1 mrg struct constraint_expr tmp; 3710 1.1 mrg tmp = new_scalar_tmp_constraint_exp ("allalltmp", true); 3711 1.1 mrg FOR_EACH_VEC_ELT (rhsc, i, rhsp) 3712 1.1 mrg process_constraint (new_constraint (tmp, *rhsp)); 3713 1.1 mrg FOR_EACH_VEC_ELT (lhsc, i, lhsp) 3714 1.1 mrg process_constraint (new_constraint (*lhsp, tmp)); 3715 1.1 mrg } 3716 1.1 mrg } 3717 1.1 mrg 3718 1.1 mrg /* Handle aggregate copies by expanding into copies of the respective 3719 1.1 mrg fields of the structures. */ 3720 1.1 mrg 3721 1.1 mrg static void 3722 1.1 mrg do_structure_copy (tree lhsop, tree rhsop) 3723 1.1 mrg { 3724 1.1 mrg struct constraint_expr *lhsp, *rhsp; 3725 1.1 mrg auto_vec<ce_s> lhsc; 3726 1.1 mrg auto_vec<ce_s> rhsc; 3727 1.1 mrg unsigned j; 3728 1.1 mrg 3729 1.1 mrg get_constraint_for (lhsop, &lhsc); 3730 1.1 mrg get_constraint_for_rhs (rhsop, &rhsc); 3731 1.1 mrg lhsp = &lhsc[0]; 3732 1.1 mrg rhsp = &rhsc[0]; 3733 1.1 mrg if (lhsp->type == DEREF 3734 1.1 mrg || (lhsp->type == ADDRESSOF && lhsp->var == anything_id) 3735 1.1 mrg || rhsp->type == DEREF) 3736 1.1 mrg { 3737 1.1 mrg if (lhsp->type == DEREF) 3738 1.1 mrg { 3739 1.1 mrg gcc_assert (lhsc.length () == 1); 3740 1.1 mrg lhsp->offset = UNKNOWN_OFFSET; 3741 1.1 mrg } 3742 1.1 mrg if (rhsp->type == DEREF) 3743 1.1 mrg { 3744 1.1 mrg gcc_assert (rhsc.length () == 1); 3745 1.1 mrg rhsp->offset = UNKNOWN_OFFSET; 3746 1.1 mrg } 3747 1.1 mrg process_all_all_constraints (lhsc, rhsc); 3748 1.1 mrg } 3749 1.1 mrg else if (lhsp->type == SCALAR 3750 1.1 mrg && (rhsp->type == SCALAR 3751 1.1 mrg || rhsp->type == ADDRESSOF)) 3752 1.1 mrg { 3753 1.1 mrg HOST_WIDE_INT lhssize, lhsoffset; 3754 1.1 mrg HOST_WIDE_INT rhssize, rhsoffset; 3755 1.1 mrg bool reverse; 3756 1.1 mrg unsigned k = 0; 3757 1.1 mrg if (!get_ref_base_and_extent_hwi (lhsop, &lhsoffset, &lhssize, &reverse) 3758 1.1 mrg || !get_ref_base_and_extent_hwi (rhsop, &rhsoffset, &rhssize, 3759 1.1 mrg &reverse)) 3760 1.1 mrg { 3761 1.1 mrg process_all_all_constraints (lhsc, rhsc); 3762 1.1 mrg return; 3763 1.1 mrg } 3764 1.1 mrg for (j = 0; lhsc.iterate (j, &lhsp);) 3765 1.1 mrg { 3766 1.1 mrg varinfo_t lhsv, rhsv; 3767 1.1 mrg rhsp = &rhsc[k]; 3768 1.1 mrg lhsv = get_varinfo (lhsp->var); 3769 1.1 mrg rhsv = get_varinfo (rhsp->var); 3770 1.1 mrg if (lhsv->may_have_pointers 3771 1.1 mrg && (lhsv->is_full_var 3772 1.1 mrg || rhsv->is_full_var 3773 1.1 mrg || ranges_overlap_p (lhsv->offset + rhsoffset, lhsv->size, 3774 1.1 mrg rhsv->offset + lhsoffset, rhsv->size))) 3775 1.1 mrg process_constraint (new_constraint (*lhsp, *rhsp)); 3776 1.1 mrg if (!rhsv->is_full_var 3777 1.1 mrg && (lhsv->is_full_var 3778 1.1 mrg || (lhsv->offset + rhsoffset + lhsv->size 3779 1.1 mrg > rhsv->offset + lhsoffset + rhsv->size))) 3780 1.1 mrg { 3781 1.1 mrg ++k; 3782 1.1 mrg if (k >= rhsc.length ()) 3783 1.1 mrg break; 3784 1.1 mrg } 3785 1.1 mrg else 3786 1.1 mrg ++j; 3787 1.1 mrg } 3788 1.1 mrg } 3789 1.1 mrg else 3790 1.1 mrg gcc_unreachable (); 3791 1.1 mrg } 3792 1.1 mrg 3793 1.1 mrg /* Create constraints ID = { rhsc }. */ 3794 1.1 mrg 3795 1.1 mrg static void 3796 1.1 mrg make_constraints_to (unsigned id, const vec<ce_s> &rhsc) 3797 1.1 mrg { 3798 1.1 mrg struct constraint_expr *c; 3799 1.1 mrg struct constraint_expr includes; 3800 1.1 mrg unsigned int j; 3801 1.1 mrg 3802 1.1 mrg includes.var = id; 3803 1.1 mrg includes.offset = 0; 3804 1.1 mrg includes.type = SCALAR; 3805 1.1 mrg 3806 1.1 mrg FOR_EACH_VEC_ELT (rhsc, j, c) 3807 1.1 mrg process_constraint (new_constraint (includes, *c)); 3808 1.1 mrg } 3809 1.1 mrg 3810 1.1 mrg /* Create a constraint ID = OP. */ 3811 1.1 mrg 3812 1.1 mrg static void 3813 1.1 mrg make_constraint_to (unsigned id, tree op) 3814 1.1 mrg { 3815 1.1 mrg auto_vec<ce_s> rhsc; 3816 1.1 mrg get_constraint_for_rhs (op, &rhsc); 3817 1.1 mrg make_constraints_to (id, rhsc); 3818 1.1 mrg } 3819 1.1 mrg 3820 1.1 mrg /* Create a constraint ID = &FROM. */ 3821 1.1 mrg 3822 1.1 mrg static void 3823 1.1 mrg make_constraint_from (varinfo_t vi, int from) 3824 1.1 mrg { 3825 1.1 mrg struct constraint_expr lhs, rhs; 3826 1.1 mrg 3827 1.1 mrg lhs.var = vi->id; 3828 1.1 mrg lhs.offset = 0; 3829 1.1 mrg lhs.type = SCALAR; 3830 1.1 mrg 3831 1.1 mrg rhs.var = from; 3832 1.1 mrg rhs.offset = 0; 3833 1.1 mrg rhs.type = ADDRESSOF; 3834 1.1 mrg process_constraint (new_constraint (lhs, rhs)); 3835 1.1 mrg } 3836 1.1 mrg 3837 1.1 mrg /* Create a constraint ID = FROM. */ 3838 1.1 mrg 3839 1.1 mrg static void 3840 1.1 mrg make_copy_constraint (varinfo_t vi, int from) 3841 1.1 mrg { 3842 1.1 mrg struct constraint_expr lhs, rhs; 3843 1.1 mrg 3844 1.1 mrg lhs.var = vi->id; 3845 1.1 mrg lhs.offset = 0; 3846 1.1 mrg lhs.type = SCALAR; 3847 1.1 mrg 3848 1.1 mrg rhs.var = from; 3849 1.1 mrg rhs.offset = 0; 3850 1.1 mrg rhs.type = SCALAR; 3851 1.1 mrg process_constraint (new_constraint (lhs, rhs)); 3852 1.1 mrg } 3853 1.1 mrg 3854 1.1 mrg /* Make constraints necessary to make OP escape. */ 3855 1.1 mrg 3856 1.1 mrg static void 3857 1.1 mrg make_escape_constraint (tree op) 3858 1.1 mrg { 3859 1.1 mrg make_constraint_to (escaped_id, op); 3860 1.1 mrg } 3861 1.1 mrg 3862 1.1 mrg /* Make constraint necessary to make all indirect references 3863 1.1 mrg from VI escape. */ 3864 1.1 mrg 3865 1.1 mrg static void 3866 1.1 mrg make_indirect_escape_constraint (varinfo_t vi) 3867 1.1 mrg { 3868 1.1 mrg struct constraint_expr lhs, rhs; 3869 1.1 mrg /* escaped = *(VAR + UNKNOWN); */ 3870 1.1 mrg lhs.type = SCALAR; 3871 1.1 mrg lhs.var = escaped_id; 3872 1.1 mrg lhs.offset = 0; 3873 1.1 mrg rhs.type = DEREF; 3874 1.1 mrg rhs.var = vi->id; 3875 1.1 mrg rhs.offset = UNKNOWN_OFFSET; 3876 1.1 mrg process_constraint (new_constraint (lhs, rhs)); 3877 1.1 mrg } 3878 1.1 mrg 3879 1.1 mrg /* Add constraints to that the solution of VI is transitively closed. */ 3880 1.1 mrg 3881 1.1 mrg static void 3882 1.1 mrg make_transitive_closure_constraints (varinfo_t vi) 3883 1.1 mrg { 3884 1.1 mrg struct constraint_expr lhs, rhs; 3885 1.1 mrg 3886 1.1 mrg /* VAR = *(VAR + UNKNOWN); */ 3887 1.1 mrg lhs.type = SCALAR; 3888 1.1 mrg lhs.var = vi->id; 3889 1.1 mrg lhs.offset = 0; 3890 1.1 mrg rhs.type = DEREF; 3891 1.1 mrg rhs.var = vi->id; 3892 1.1 mrg rhs.offset = UNKNOWN_OFFSET; 3893 1.1 mrg process_constraint (new_constraint (lhs, rhs)); 3894 1.1 mrg } 3895 1.1 mrg 3896 1.1 mrg /* Add constraints to that the solution of VI has all subvariables added. */ 3897 1.1 mrg 3898 1.1 mrg static void 3899 1.1 mrg make_any_offset_constraints (varinfo_t vi) 3900 1.1 mrg { 3901 1.1 mrg struct constraint_expr lhs, rhs; 3902 1.1 mrg 3903 1.1 mrg /* VAR = VAR + UNKNOWN; */ 3904 1.1 mrg lhs.type = SCALAR; 3905 1.1 mrg lhs.var = vi->id; 3906 1.1 mrg lhs.offset = 0; 3907 1.1 mrg rhs.type = SCALAR; 3908 1.1 mrg rhs.var = vi->id; 3909 1.1 mrg rhs.offset = UNKNOWN_OFFSET; 3910 1.1 mrg process_constraint (new_constraint (lhs, rhs)); 3911 1.1 mrg } 3912 1.1 mrg 3913 1.1 mrg /* Temporary storage for fake var decls. */ 3914 1.1 mrg struct obstack fake_var_decl_obstack; 3915 1.1 mrg 3916 1.1 mrg /* Build a fake VAR_DECL acting as referrer to a DECL_UID. */ 3917 1.1 mrg 3918 1.1 mrg static tree 3919 1.1 mrg build_fake_var_decl (tree type) 3920 1.1 mrg { 3921 1.1 mrg tree decl = (tree) XOBNEW (&fake_var_decl_obstack, struct tree_var_decl); 3922 1.1 mrg memset (decl, 0, sizeof (struct tree_var_decl)); 3923 1.1 mrg TREE_SET_CODE (decl, VAR_DECL); 3924 1.1 mrg TREE_TYPE (decl) = type; 3925 1.1 mrg DECL_UID (decl) = allocate_decl_uid (); 3926 1.1 mrg SET_DECL_PT_UID (decl, -1); 3927 1.1 mrg layout_decl (decl, 0); 3928 1.1 mrg return decl; 3929 1.1 mrg } 3930 1.1 mrg 3931 1.1 mrg /* Create a new artificial heap variable with NAME. 3932 1.1 mrg Return the created variable. */ 3933 1.1 mrg 3934 1.1 mrg static varinfo_t 3935 1.1 mrg make_heapvar (const char *name, bool add_id) 3936 1.1 mrg { 3937 1.1 mrg varinfo_t vi; 3938 1.1 mrg tree heapvar; 3939 1.1 mrg 3940 1.1 mrg heapvar = build_fake_var_decl (ptr_type_node); 3941 1.1 mrg DECL_EXTERNAL (heapvar) = 1; 3942 1.1 mrg 3943 1.1 mrg vi = new_var_info (heapvar, name, add_id); 3944 1.1 mrg vi->is_heap_var = true; 3945 1.1 mrg vi->is_unknown_size_var = true; 3946 1.1 mrg vi->offset = 0; 3947 1.1 mrg vi->fullsize = ~0; 3948 1.1 mrg vi->size = ~0; 3949 1.1 mrg vi->is_full_var = true; 3950 1.1 mrg insert_vi_for_tree (heapvar, vi); 3951 1.1 mrg 3952 1.1 mrg return vi; 3953 1.1 mrg } 3954 1.1 mrg 3955 1.1 mrg /* Create a new artificial heap variable with NAME and make a 3956 1.1 mrg constraint from it to LHS. Set flags according to a tag used 3957 1.1 mrg for tracking restrict pointers. */ 3958 1.1 mrg 3959 1.1 mrg static varinfo_t 3960 1.1 mrg make_constraint_from_restrict (varinfo_t lhs, const char *name, bool add_id) 3961 1.1 mrg { 3962 1.1 mrg varinfo_t vi = make_heapvar (name, add_id); 3963 1.1 mrg vi->is_restrict_var = 1; 3964 1.1 mrg vi->is_global_var = 1; 3965 1.1 mrg vi->may_have_pointers = 1; 3966 1.1 mrg make_constraint_from (lhs, vi->id); 3967 1.1 mrg return vi; 3968 1.1 mrg } 3969 1.1 mrg 3970 1.1 mrg /* Create a new artificial heap variable with NAME and make a 3971 1.1 mrg constraint from it to LHS. Set flags according to a tag used 3972 1.1 mrg for tracking restrict pointers and make the artificial heap 3973 1.1 mrg point to global memory. */ 3974 1.1 mrg 3975 1.1 mrg static varinfo_t 3976 1.1 mrg make_constraint_from_global_restrict (varinfo_t lhs, const char *name, 3977 1.1 mrg bool add_id) 3978 1.1 mrg { 3979 1.1 mrg varinfo_t vi = make_constraint_from_restrict (lhs, name, add_id); 3980 1.1 mrg make_copy_constraint (vi, nonlocal_id); 3981 1.1 mrg return vi; 3982 1.1 mrg } 3983 1.1 mrg 3984 1.1 mrg /* In IPA mode there are varinfos for different aspects of reach 3985 1.1 mrg function designator. One for the points-to set of the return 3986 1.1 mrg value, one for the variables that are clobbered by the function, 3987 1.1 mrg one for its uses and one for each parameter (including a single 3988 1.1 mrg glob for remaining variadic arguments). */ 3989 1.1 mrg 3990 1.1 mrg enum { fi_clobbers = 1, fi_uses = 2, 3991 1.1 mrg fi_static_chain = 3, fi_result = 4, fi_parm_base = 5 }; 3992 1.1 mrg 3993 1.1 mrg /* Get a constraint for the requested part of a function designator FI 3994 1.1 mrg when operating in IPA mode. */ 3995 1.1 mrg 3996 1.1 mrg static struct constraint_expr 3997 1.1 mrg get_function_part_constraint (varinfo_t fi, unsigned part) 3998 1.1 mrg { 3999 1.1 mrg struct constraint_expr c; 4000 1.1 mrg 4001 1.1 mrg gcc_assert (in_ipa_mode); 4002 1.1 mrg 4003 1.1 mrg if (fi->id == anything_id) 4004 1.1 mrg { 4005 1.1 mrg /* ??? We probably should have a ANYFN special variable. */ 4006 1.1 mrg c.var = anything_id; 4007 1.1 mrg c.offset = 0; 4008 1.1 mrg c.type = SCALAR; 4009 1.1 mrg } 4010 1.1 mrg else if (fi->decl && TREE_CODE (fi->decl) == FUNCTION_DECL) 4011 1.1 mrg { 4012 1.1 mrg varinfo_t ai = first_vi_for_offset (fi, part); 4013 1.1 mrg if (ai) 4014 1.1 mrg c.var = ai->id; 4015 1.1 mrg else 4016 1.1 mrg c.var = anything_id; 4017 1.1 mrg c.offset = 0; 4018 1.1 mrg c.type = SCALAR; 4019 1.1 mrg } 4020 1.1 mrg else 4021 1.1 mrg { 4022 1.1 mrg c.var = fi->id; 4023 1.1 mrg c.offset = part; 4024 1.1 mrg c.type = DEREF; 4025 1.1 mrg } 4026 1.1 mrg 4027 1.1 mrg return c; 4028 1.1 mrg } 4029 1.1 mrg 4030 1.1 mrg /* Produce constraints for argument ARG of call STMT with eaf flags 4031 1.1 mrg FLAGS. RESULTS is array holding constraints for return value. 4032 1.1 mrg CALLESCAPE_ID is variable where call loocal escapes are added. 4033 1.1 mrg WRITES_GLOVEL_MEMORY is true if callee may write global memory. */ 4034 1.1 mrg 4035 1.1 mrg static void 4036 1.1 mrg handle_call_arg (gcall *stmt, tree arg, vec<ce_s> *results, int flags, 4037 1.1 mrg int callescape_id, bool writes_global_memory) 4038 1.1 mrg { 4039 1.1 mrg int relevant_indirect_flags = EAF_NO_INDIRECT_CLOBBER | EAF_NO_INDIRECT_READ 4040 1.1 mrg | EAF_NO_INDIRECT_ESCAPE; 4041 1.1 mrg int relevant_flags = relevant_indirect_flags 4042 1.1 mrg | EAF_NO_DIRECT_CLOBBER 4043 1.1 mrg | EAF_NO_DIRECT_READ 4044 1.1 mrg | EAF_NO_DIRECT_ESCAPE; 4045 1.1 mrg if (gimple_call_lhs (stmt)) 4046 1.1 mrg { 4047 1.1 mrg relevant_flags |= EAF_NOT_RETURNED_DIRECTLY | EAF_NOT_RETURNED_INDIRECTLY; 4048 1.1 mrg relevant_indirect_flags |= EAF_NOT_RETURNED_INDIRECTLY; 4049 1.1 mrg 4050 1.1 mrg /* If value is never read from it can not be returned indirectly 4051 1.1 mrg (except through the escape solution). 4052 1.1 mrg For all flags we get these implications right except for 4053 1.1 mrg not_returned because we miss return functions in ipa-prop. */ 4054 1.1 mrg 4055 1.1 mrg if (flags & EAF_NO_DIRECT_READ) 4056 1.1 mrg flags |= EAF_NOT_RETURNED_INDIRECTLY; 4057 1.1 mrg } 4058 1.1 mrg 4059 1.1 mrg /* If the argument is not used we can ignore it. 4060 1.1 mrg Similarly argument is invisile for us if it not clobbered, does not 4061 1.1 mrg escape, is not read and can not be returned. */ 4062 1.1 mrg if ((flags & EAF_UNUSED) || ((flags & relevant_flags) == relevant_flags)) 4063 1.1 mrg return; 4064 1.1 mrg 4065 1.1 mrg /* Produce varinfo for direct accesses to ARG. */ 4066 1.1 mrg varinfo_t tem = new_var_info (NULL_TREE, "callarg", true); 4067 1.1 mrg tem->is_reg_var = true; 4068 1.1 mrg make_constraint_to (tem->id, arg); 4069 1.1 mrg make_any_offset_constraints (tem); 4070 1.1 mrg 4071 1.1 mrg bool callarg_transitive = false; 4072 1.1 mrg 4073 1.1 mrg /* As an compile time optimization if we make no difference between 4074 1.1 mrg direct and indirect accesses make arg transitively closed. 4075 1.1 mrg This avoids the need to build indir arg and do everything twice. */ 4076 1.1 mrg if (((flags & EAF_NO_INDIRECT_CLOBBER) != 0) 4077 1.1 mrg == ((flags & EAF_NO_DIRECT_CLOBBER) != 0) 4078 1.1 mrg && (((flags & EAF_NO_INDIRECT_READ) != 0) 4079 1.1 mrg == ((flags & EAF_NO_DIRECT_READ) != 0)) 4080 1.1 mrg && (((flags & EAF_NO_INDIRECT_ESCAPE) != 0) 4081 1.1 mrg == ((flags & EAF_NO_DIRECT_ESCAPE) != 0)) 4082 1.1 mrg && (((flags & EAF_NOT_RETURNED_INDIRECTLY) != 0) 4083 1.1 mrg == ((flags & EAF_NOT_RETURNED_DIRECTLY) != 0))) 4084 1.1 mrg { 4085 1.1 mrg make_transitive_closure_constraints (tem); 4086 1.1 mrg callarg_transitive = true; 4087 1.1 mrg gcc_checking_assert (!(flags & EAF_NO_DIRECT_READ)); 4088 1.1 mrg } 4089 1.1 mrg 4090 1.1 mrg /* If necessary, produce varinfo for indirect accesses to ARG. */ 4091 1.1 mrg varinfo_t indir_tem = NULL; 4092 1.1 mrg if (!callarg_transitive 4093 1.1 mrg && (flags & relevant_indirect_flags) != relevant_indirect_flags) 4094 1.1 mrg { 4095 1.1 mrg struct constraint_expr lhs, rhs; 4096 1.1 mrg indir_tem = new_var_info (NULL_TREE, "indircallarg", true); 4097 1.1 mrg indir_tem->is_reg_var = true; 4098 1.1 mrg 4099 1.1 mrg /* indir_term = *tem. */ 4100 1.1 mrg lhs.type = SCALAR; 4101 1.1 mrg lhs.var = indir_tem->id; 4102 1.1 mrg lhs.offset = 0; 4103 1.1 mrg 4104 1.1 mrg rhs.type = DEREF; 4105 1.1 mrg rhs.var = tem->id; 4106 1.1 mrg rhs.offset = UNKNOWN_OFFSET; 4107 1.1 mrg process_constraint (new_constraint (lhs, rhs)); 4108 1.1 mrg 4109 1.1 mrg make_any_offset_constraints (indir_tem); 4110 1.1 mrg 4111 1.1 mrg /* If we do not read indirectly there is no need for transitive closure. 4112 1.1 mrg We know there is only one level of indirection. */ 4113 1.1 mrg if (!(flags & EAF_NO_INDIRECT_READ)) 4114 1.1 mrg make_transitive_closure_constraints (indir_tem); 4115 1.1 mrg gcc_checking_assert (!(flags & EAF_NO_DIRECT_READ)); 4116 1.1 mrg } 4117 1.1 mrg 4118 1.1 mrg if (gimple_call_lhs (stmt)) 4119 1.1 mrg { 4120 1.1 mrg if (!(flags & EAF_NOT_RETURNED_DIRECTLY)) 4121 1.1 mrg { 4122 1.1 mrg struct constraint_expr cexpr; 4123 1.1 mrg cexpr.var = tem->id; 4124 1.1 mrg cexpr.type = SCALAR; 4125 1.1 mrg cexpr.offset = 0; 4126 1.1 mrg results->safe_push (cexpr); 4127 1.1 mrg } 4128 1.1 mrg if (!callarg_transitive & !(flags & EAF_NOT_RETURNED_INDIRECTLY)) 4129 1.1 mrg { 4130 1.1 mrg struct constraint_expr cexpr; 4131 1.1 mrg cexpr.var = indir_tem->id; 4132 1.1 mrg cexpr.type = SCALAR; 4133 1.1 mrg cexpr.offset = 0; 4134 1.1 mrg results->safe_push (cexpr); 4135 1.1 mrg } 4136 1.1 mrg } 4137 1.1 mrg 4138 1.1 mrg if (!(flags & EAF_NO_DIRECT_READ)) 4139 1.1 mrg { 4140 1.1 mrg varinfo_t uses = get_call_use_vi (stmt); 4141 1.1 mrg make_copy_constraint (uses, tem->id); 4142 1.1 mrg if (!callarg_transitive & !(flags & EAF_NO_INDIRECT_READ)) 4143 1.1 mrg make_copy_constraint (uses, indir_tem->id); 4144 1.1 mrg } 4145 1.1 mrg else 4146 1.1 mrg /* To read indirectly we need to read directly. */ 4147 1.1 mrg gcc_checking_assert (flags & EAF_NO_INDIRECT_READ); 4148 1.1 mrg 4149 1.1 mrg if (!(flags & EAF_NO_DIRECT_CLOBBER)) 4150 1.1 mrg { 4151 1.1 mrg struct constraint_expr lhs, rhs; 4152 1.1 mrg 4153 1.1 mrg /* *arg = callescape. */ 4154 1.1 mrg lhs.type = DEREF; 4155 1.1 mrg lhs.var = tem->id; 4156 1.1 mrg lhs.offset = 0; 4157 1.1 mrg 4158 1.1 mrg rhs.type = SCALAR; 4159 1.1 mrg rhs.var = callescape_id; 4160 1.1 mrg rhs.offset = 0; 4161 1.1 mrg process_constraint (new_constraint (lhs, rhs)); 4162 1.1 mrg 4163 1.1 mrg /* callclobbered = arg. */ 4164 1.1 mrg make_copy_constraint (get_call_clobber_vi (stmt), tem->id); 4165 1.1 mrg } 4166 1.1 mrg if (!callarg_transitive & !(flags & EAF_NO_INDIRECT_CLOBBER)) 4167 1.1 mrg { 4168 1.1 mrg struct constraint_expr lhs, rhs; 4169 1.1 mrg 4170 1.1 mrg /* *indir_arg = callescape. */ 4171 1.1 mrg lhs.type = DEREF; 4172 1.1 mrg lhs.var = indir_tem->id; 4173 1.1 mrg lhs.offset = 0; 4174 1.1 mrg 4175 1.1 mrg rhs.type = SCALAR; 4176 1.1 mrg rhs.var = callescape_id; 4177 1.1 mrg rhs.offset = 0; 4178 1.1 mrg process_constraint (new_constraint (lhs, rhs)); 4179 1.1 mrg 4180 1.1 mrg /* callclobbered = indir_arg. */ 4181 1.1 mrg make_copy_constraint (get_call_clobber_vi (stmt), indir_tem->id); 4182 1.1 mrg } 4183 1.1 mrg 4184 1.1 mrg if (!(flags & (EAF_NO_DIRECT_ESCAPE | EAF_NO_INDIRECT_ESCAPE))) 4185 1.1 mrg { 4186 1.1 mrg struct constraint_expr lhs, rhs; 4187 1.1 mrg 4188 1.1 mrg /* callescape = arg; */ 4189 1.1 mrg lhs.var = callescape_id; 4190 1.1 mrg lhs.offset = 0; 4191 1.1 mrg lhs.type = SCALAR; 4192 1.1 mrg 4193 1.1 mrg rhs.var = tem->id; 4194 1.1 mrg rhs.offset = 0; 4195 1.1 mrg rhs.type = SCALAR; 4196 1.1 mrg process_constraint (new_constraint (lhs, rhs)); 4197 1.1 mrg 4198 1.1 mrg if (writes_global_memory) 4199 1.1 mrg make_escape_constraint (arg); 4200 1.1 mrg } 4201 1.1 mrg else if (!callarg_transitive & !(flags & EAF_NO_INDIRECT_ESCAPE)) 4202 1.1 mrg { 4203 1.1 mrg struct constraint_expr lhs, rhs; 4204 1.1 mrg 4205 1.1 mrg /* callescape = *(indir_arg + UNKNOWN); */ 4206 1.1 mrg lhs.var = callescape_id; 4207 1.1 mrg lhs.offset = 0; 4208 1.1 mrg lhs.type = SCALAR; 4209 1.1 mrg 4210 1.1 mrg rhs.var = indir_tem->id; 4211 1.1 mrg rhs.offset = 0; 4212 1.1 mrg rhs.type = SCALAR; 4213 1.1 mrg process_constraint (new_constraint (lhs, rhs)); 4214 1.1 mrg 4215 1.1 mrg if (writes_global_memory) 4216 1.1 mrg make_indirect_escape_constraint (tem); 4217 1.1 mrg } 4218 1.1 mrg } 4219 1.1 mrg 4220 1.1 mrg /* Determine global memory access of call STMT and update 4221 1.1 mrg WRITES_GLOBAL_MEMORY, READS_GLOBAL_MEMORY and USES_GLOBAL_MEMORY. */ 4222 1.1 mrg 4223 1.1 mrg static void 4224 1.1 mrg determine_global_memory_access (gcall *stmt, 4225 1.1 mrg bool *writes_global_memory, 4226 1.1 mrg bool *reads_global_memory, 4227 1.1 mrg bool *uses_global_memory) 4228 1.1 mrg { 4229 1.1 mrg tree callee; 4230 1.1 mrg cgraph_node *node; 4231 1.1 mrg modref_summary *summary; 4232 1.1 mrg 4233 1.1 mrg /* We need to detrmine reads to set uses. */ 4234 1.1 mrg gcc_assert (!uses_global_memory || reads_global_memory); 4235 1.1 mrg 4236 1.1 mrg if ((callee = gimple_call_fndecl (stmt)) != NULL_TREE 4237 1.1 mrg && (node = cgraph_node::get (callee)) != NULL 4238 1.1 mrg && (summary = get_modref_function_summary (node))) 4239 1.1 mrg { 4240 1.1 mrg if (writes_global_memory && *writes_global_memory) 4241 1.1 mrg *writes_global_memory = summary->global_memory_written; 4242 1.1 mrg if (reads_global_memory && *reads_global_memory) 4243 1.1 mrg *reads_global_memory = summary->global_memory_read; 4244 1.1 mrg if (reads_global_memory && uses_global_memory 4245 1.1 mrg && !summary->calls_interposable 4246 1.1 mrg && !*reads_global_memory && node->binds_to_current_def_p ()) 4247 1.1 mrg *uses_global_memory = false; 4248 1.1 mrg } 4249 1.1 mrg if ((writes_global_memory && *writes_global_memory) 4250 1.1 mrg || (uses_global_memory && *uses_global_memory) 4251 1.1 mrg || (reads_global_memory && *reads_global_memory)) 4252 1.1 mrg { 4253 1.1 mrg attr_fnspec fnspec = gimple_call_fnspec (stmt); 4254 1.1 mrg if (fnspec.known_p ()) 4255 1.1 mrg { 4256 1.1 mrg if (writes_global_memory 4257 1.1 mrg && !fnspec.global_memory_written_p ()) 4258 1.1 mrg *writes_global_memory = false; 4259 1.1 mrg if (reads_global_memory && !fnspec.global_memory_read_p ()) 4260 1.1 mrg { 4261 1.1 mrg *reads_global_memory = false; 4262 1.1 mrg if (uses_global_memory) 4263 1.1 mrg *uses_global_memory = false; 4264 1.1 mrg } 4265 1.1 mrg } 4266 1.1 mrg } 4267 1.1 mrg } 4268 1.1 mrg 4269 1.1 mrg /* For non-IPA mode, generate constraints necessary for a call on the 4270 1.1 mrg RHS and collect return value constraint to RESULTS to be used later in 4271 1.1 mrg handle_lhs_call. 4272 1.1 mrg 4273 1.1 mrg IMPLICIT_EAF_FLAGS are added to each function argument. If 4274 1.1 mrg WRITES_GLOBAL_MEMORY is true function is assumed to possibly write to global 4275 1.1 mrg memory. Similar for READS_GLOBAL_MEMORY. */ 4276 1.1 mrg 4277 1.1 mrg static void 4278 1.1 mrg handle_rhs_call (gcall *stmt, vec<ce_s> *results, 4279 1.1 mrg int implicit_eaf_flags, 4280 1.1 mrg bool writes_global_memory, 4281 1.1 mrg bool reads_global_memory) 4282 1.1 mrg { 4283 1.1 mrg determine_global_memory_access (stmt, &writes_global_memory, 4284 1.1 mrg &reads_global_memory, 4285 1.1 mrg NULL); 4286 1.1 mrg 4287 1.1 mrg varinfo_t callescape = new_var_info (NULL_TREE, "callescape", true); 4288 1.1 mrg 4289 1.1 mrg /* If function can use global memory, add it to callescape 4290 1.1 mrg and to possible return values. If not we can still use/return addresses 4291 1.1 mrg of global symbols. */ 4292 1.1 mrg struct constraint_expr lhs, rhs; 4293 1.1 mrg 4294 1.1 mrg lhs.type = SCALAR; 4295 1.1 mrg lhs.var = callescape->id; 4296 1.1 mrg lhs.offset = 0; 4297 1.1 mrg 4298 1.1 mrg rhs.type = reads_global_memory ? SCALAR : ADDRESSOF; 4299 1.1 mrg rhs.var = nonlocal_id; 4300 1.1 mrg rhs.offset = 0; 4301 1.1 mrg 4302 1.1 mrg process_constraint (new_constraint (lhs, rhs)); 4303 1.1 mrg results->safe_push (rhs); 4304 1.1 mrg 4305 1.1 mrg varinfo_t uses = get_call_use_vi (stmt); 4306 1.1 mrg make_copy_constraint (uses, callescape->id); 4307 1.1 mrg 4308 1.1 mrg for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i) 4309 1.1 mrg { 4310 1.1 mrg tree arg = gimple_call_arg (stmt, i); 4311 1.1 mrg int flags = gimple_call_arg_flags (stmt, i); 4312 1.1 mrg handle_call_arg (stmt, arg, results, 4313 1.1 mrg flags | implicit_eaf_flags, 4314 1.1 mrg callescape->id, writes_global_memory); 4315 1.1 mrg } 4316 1.1 mrg 4317 1.1 mrg /* The static chain escapes as well. */ 4318 1.1 mrg if (gimple_call_chain (stmt)) 4319 1.1 mrg handle_call_arg (stmt, gimple_call_chain (stmt), results, 4320 1.1 mrg implicit_eaf_flags 4321 1.1 mrg | gimple_call_static_chain_flags (stmt), 4322 1.1 mrg callescape->id, writes_global_memory); 4323 1.1 mrg 4324 1.1 mrg /* And if we applied NRV the address of the return slot escapes as well. */ 4325 1.1 mrg if (gimple_call_return_slot_opt_p (stmt) 4326 1.1 mrg && gimple_call_lhs (stmt) != NULL_TREE 4327 1.1 mrg && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (stmt)))) 4328 1.1 mrg { 4329 1.1 mrg int flags = gimple_call_retslot_flags (stmt); 4330 1.1 mrg const int relevant_flags = EAF_NO_DIRECT_ESCAPE 4331 1.1 mrg | EAF_NOT_RETURNED_DIRECTLY; 4332 1.1 mrg 4333 1.1 mrg if (!(flags & EAF_UNUSED) && (flags & relevant_flags) != relevant_flags) 4334 1.1 mrg { 4335 1.1 mrg auto_vec<ce_s> tmpc; 4336 1.1 mrg 4337 1.1 mrg get_constraint_for_address_of (gimple_call_lhs (stmt), &tmpc); 4338 1.1 mrg 4339 1.1 mrg if (!(flags & EAF_NO_DIRECT_ESCAPE)) 4340 1.1 mrg { 4341 1.1 mrg make_constraints_to (callescape->id, tmpc); 4342 1.1 mrg if (writes_global_memory) 4343 1.1 mrg make_constraints_to (escaped_id, tmpc); 4344 1.1 mrg } 4345 1.1 mrg if (!(flags & EAF_NOT_RETURNED_DIRECTLY)) 4346 1.1 mrg { 4347 1.1 mrg struct constraint_expr *c; 4348 1.1 mrg unsigned i; 4349 1.1 mrg FOR_EACH_VEC_ELT (tmpc, i, c) 4350 1.1 mrg results->safe_push (*c); 4351 1.1 mrg } 4352 1.1 mrg } 4353 1.1 mrg } 4354 1.1 mrg } 4355 1.1 mrg 4356 1.1 mrg /* For non-IPA mode, generate constraints necessary for a call 4357 1.1 mrg that returns a pointer and assigns it to LHS. This simply makes 4358 1.1 mrg the LHS point to global and escaped variables. */ 4359 1.1 mrg 4360 1.1 mrg static void 4361 1.1 mrg handle_lhs_call (gcall *stmt, tree lhs, int flags, vec<ce_s> &rhsc, 4362 1.1 mrg tree fndecl) 4363 1.1 mrg { 4364 1.1 mrg auto_vec<ce_s> lhsc; 4365 1.1 mrg 4366 1.1 mrg get_constraint_for (lhs, &lhsc); 4367 1.1 mrg /* If the store is to a global decl make sure to 4368 1.1 mrg add proper escape constraints. */ 4369 1.1 mrg lhs = get_base_address (lhs); 4370 1.1 mrg if (lhs 4371 1.1 mrg && DECL_P (lhs) 4372 1.1 mrg && is_global_var (lhs)) 4373 1.1 mrg { 4374 1.1 mrg struct constraint_expr tmpc; 4375 1.1 mrg tmpc.var = escaped_id; 4376 1.1 mrg tmpc.offset = 0; 4377 1.1 mrg tmpc.type = SCALAR; 4378 1.1 mrg lhsc.safe_push (tmpc); 4379 1.1 mrg } 4380 1.1 mrg 4381 1.1 mrg /* If the call returns an argument unmodified override the rhs 4382 1.1 mrg constraints. */ 4383 1.1 mrg if (flags & ERF_RETURNS_ARG 4384 1.1 mrg && (flags & ERF_RETURN_ARG_MASK) < gimple_call_num_args (stmt)) 4385 1.1 mrg { 4386 1.1 mrg tree arg; 4387 1.1 mrg rhsc.create (0); 4388 1.1 mrg arg = gimple_call_arg (stmt, flags & ERF_RETURN_ARG_MASK); 4389 1.1 mrg get_constraint_for (arg, &rhsc); 4390 1.1 mrg process_all_all_constraints (lhsc, rhsc); 4391 1.1 mrg rhsc.release (); 4392 1.1 mrg } 4393 1.1 mrg else if (flags & ERF_NOALIAS) 4394 1.1 mrg { 4395 1.1 mrg varinfo_t vi; 4396 1.1 mrg struct constraint_expr tmpc; 4397 1.1 mrg rhsc.create (0); 4398 1.1 mrg vi = make_heapvar ("HEAP", true); 4399 1.1 mrg /* We are marking allocated storage local, we deal with it becoming 4400 1.1 mrg global by escaping and setting of vars_contains_escaped_heap. */ 4401 1.1 mrg DECL_EXTERNAL (vi->decl) = 0; 4402 1.1 mrg vi->is_global_var = 0; 4403 1.1 mrg /* If this is not a real malloc call assume the memory was 4404 1.1 mrg initialized and thus may point to global memory. All 4405 1.1 mrg builtin functions with the malloc attribute behave in a sane way. */ 4406 1.1 mrg if (!fndecl 4407 1.1 mrg || !fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)) 4408 1.1 mrg make_constraint_from (vi, nonlocal_id); 4409 1.1 mrg tmpc.var = vi->id; 4410 1.1 mrg tmpc.offset = 0; 4411 1.1 mrg tmpc.type = ADDRESSOF; 4412 1.1 mrg rhsc.safe_push (tmpc); 4413 1.1 mrg process_all_all_constraints (lhsc, rhsc); 4414 1.1 mrg rhsc.release (); 4415 1.1 mrg } 4416 1.1 mrg else 4417 1.1 mrg process_all_all_constraints (lhsc, rhsc); 4418 1.1 mrg } 4419 1.1 mrg 4420 1.1 mrg 4421 1.1 mrg /* Return the varinfo for the callee of CALL. */ 4422 1.1 mrg 4423 1.1 mrg static varinfo_t 4424 1.1 mrg get_fi_for_callee (gcall *call) 4425 1.1 mrg { 4426 1.1 mrg tree decl, fn = gimple_call_fn (call); 4427 1.1 mrg 4428 1.1 mrg if (fn && TREE_CODE (fn) == OBJ_TYPE_REF) 4429 1.1 mrg fn = OBJ_TYPE_REF_EXPR (fn); 4430 1.1 mrg 4431 1.1 mrg /* If we can directly resolve the function being called, do so. 4432 1.1 mrg Otherwise, it must be some sort of indirect expression that 4433 1.1 mrg we should still be able to handle. */ 4434 1.1 mrg decl = gimple_call_addr_fndecl (fn); 4435 1.1 mrg if (decl) 4436 1.1 mrg return get_vi_for_tree (decl); 4437 1.1 mrg 4438 1.1 mrg /* If the function is anything other than a SSA name pointer we have no 4439 1.1 mrg clue and should be getting ANYFN (well, ANYTHING for now). */ 4440 1.1 mrg if (!fn || TREE_CODE (fn) != SSA_NAME) 4441 1.1 mrg return get_varinfo (anything_id); 4442 1.1 mrg 4443 1.1 mrg if (SSA_NAME_IS_DEFAULT_DEF (fn) 4444 1.1 mrg && (TREE_CODE (SSA_NAME_VAR (fn)) == PARM_DECL 4445 1.1 mrg || TREE_CODE (SSA_NAME_VAR (fn)) == RESULT_DECL)) 4446 1.1 mrg fn = SSA_NAME_VAR (fn); 4447 1.1 mrg 4448 1.1 mrg return get_vi_for_tree (fn); 4449 1.1 mrg } 4450 1.1 mrg 4451 1.1 mrg /* Create constraints for assigning call argument ARG to the incoming parameter 4452 1.1 mrg INDEX of function FI. */ 4453 1.1 mrg 4454 1.1 mrg static void 4455 1.1 mrg find_func_aliases_for_call_arg (varinfo_t fi, unsigned index, tree arg) 4456 1.1 mrg { 4457 1.1 mrg struct constraint_expr lhs; 4458 1.1 mrg lhs = get_function_part_constraint (fi, fi_parm_base + index); 4459 1.1 mrg 4460 1.1 mrg auto_vec<ce_s, 2> rhsc; 4461 1.1 mrg get_constraint_for_rhs (arg, &rhsc); 4462 1.1 mrg 4463 1.1 mrg unsigned j; 4464 1.1 mrg struct constraint_expr *rhsp; 4465 1.1 mrg FOR_EACH_VEC_ELT (rhsc, j, rhsp) 4466 1.1 mrg process_constraint (new_constraint (lhs, *rhsp)); 4467 1.1 mrg } 4468 1.1 mrg 4469 1.1 mrg /* Return true if FNDECL may be part of another lto partition. */ 4470 1.1 mrg 4471 1.1 mrg static bool 4472 1.1 mrg fndecl_maybe_in_other_partition (tree fndecl) 4473 1.1 mrg { 4474 1.1 mrg cgraph_node *fn_node = cgraph_node::get (fndecl); 4475 1.1 mrg if (fn_node == NULL) 4476 1.1 mrg return true; 4477 1.1 mrg 4478 1.1 mrg return fn_node->in_other_partition; 4479 1.1 mrg } 4480 1.1 mrg 4481 1.1 mrg /* Create constraints for the builtin call T. Return true if the call 4482 1.1 mrg was handled, otherwise false. */ 4483 1.1 mrg 4484 1.1 mrg static bool 4485 1.1 mrg find_func_aliases_for_builtin_call (struct function *fn, gcall *t) 4486 1.1 mrg { 4487 1.1 mrg tree fndecl = gimple_call_fndecl (t); 4488 1.1 mrg auto_vec<ce_s, 2> lhsc; 4489 1.1 mrg auto_vec<ce_s, 4> rhsc; 4490 1.1 mrg varinfo_t fi; 4491 1.1 mrg 4492 1.1 mrg if (gimple_call_builtin_p (t, BUILT_IN_NORMAL)) 4493 1.1 mrg /* ??? All builtins that are handled here need to be handled 4494 1.1 mrg in the alias-oracle query functions explicitly! */ 4495 1.1 mrg switch (DECL_FUNCTION_CODE (fndecl)) 4496 1.1 mrg { 4497 1.1 mrg /* All the following functions return a pointer to the same object 4498 1.1 mrg as their first argument points to. The functions do not add 4499 1.1 mrg to the ESCAPED solution. The functions make the first argument 4500 1.1 mrg pointed to memory point to what the second argument pointed to 4501 1.1 mrg memory points to. */ 4502 1.1 mrg case BUILT_IN_STRCPY: 4503 1.1 mrg case BUILT_IN_STRNCPY: 4504 1.1 mrg case BUILT_IN_BCOPY: 4505 1.1 mrg case BUILT_IN_MEMCPY: 4506 1.1 mrg case BUILT_IN_MEMMOVE: 4507 1.1 mrg case BUILT_IN_MEMPCPY: 4508 1.1 mrg case BUILT_IN_STPCPY: 4509 1.1 mrg case BUILT_IN_STPNCPY: 4510 1.1 mrg case BUILT_IN_STRCAT: 4511 1.1 mrg case BUILT_IN_STRNCAT: 4512 1.1 mrg case BUILT_IN_STRCPY_CHK: 4513 1.1 mrg case BUILT_IN_STRNCPY_CHK: 4514 1.1 mrg case BUILT_IN_MEMCPY_CHK: 4515 1.1 mrg case BUILT_IN_MEMMOVE_CHK: 4516 1.1 mrg case BUILT_IN_MEMPCPY_CHK: 4517 1.1 mrg case BUILT_IN_STPCPY_CHK: 4518 1.1 mrg case BUILT_IN_STPNCPY_CHK: 4519 1.1 mrg case BUILT_IN_STRCAT_CHK: 4520 1.1 mrg case BUILT_IN_STRNCAT_CHK: 4521 1.1 mrg case BUILT_IN_TM_MEMCPY: 4522 1.1 mrg case BUILT_IN_TM_MEMMOVE: 4523 1.1 mrg { 4524 1.1 mrg tree res = gimple_call_lhs (t); 4525 1.1 mrg tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl) 4526 1.1 mrg == BUILT_IN_BCOPY ? 1 : 0)); 4527 1.1 mrg tree src = gimple_call_arg (t, (DECL_FUNCTION_CODE (fndecl) 4528 1.1 mrg == BUILT_IN_BCOPY ? 0 : 1)); 4529 1.1 mrg if (res != NULL_TREE) 4530 1.1 mrg { 4531 1.1 mrg get_constraint_for (res, &lhsc); 4532 1.1 mrg if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMPCPY 4533 1.1 mrg || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPCPY 4534 1.1 mrg || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPNCPY 4535 1.1 mrg || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMPCPY_CHK 4536 1.1 mrg || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPCPY_CHK 4537 1.1 mrg || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STPNCPY_CHK) 4538 1.1 mrg get_constraint_for_ptr_offset (dest, NULL_TREE, &rhsc); 4539 1.1 mrg else 4540 1.1 mrg get_constraint_for (dest, &rhsc); 4541 1.1 mrg process_all_all_constraints (lhsc, rhsc); 4542 1.1 mrg lhsc.truncate (0); 4543 1.1 mrg rhsc.truncate (0); 4544 1.1 mrg } 4545 1.1 mrg get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc); 4546 1.1 mrg get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc); 4547 1.1 mrg do_deref (&lhsc); 4548 1.1 mrg do_deref (&rhsc); 4549 1.1 mrg process_all_all_constraints (lhsc, rhsc); 4550 1.1 mrg return true; 4551 1.1 mrg } 4552 1.1 mrg case BUILT_IN_MEMSET: 4553 1.1 mrg case BUILT_IN_MEMSET_CHK: 4554 1.1 mrg case BUILT_IN_TM_MEMSET: 4555 1.1 mrg { 4556 1.1 mrg tree res = gimple_call_lhs (t); 4557 1.1 mrg tree dest = gimple_call_arg (t, 0); 4558 1.1 mrg unsigned i; 4559 1.1 mrg ce_s *lhsp; 4560 1.1 mrg struct constraint_expr ac; 4561 1.1 mrg if (res != NULL_TREE) 4562 1.1 mrg { 4563 1.1 mrg get_constraint_for (res, &lhsc); 4564 1.1 mrg get_constraint_for (dest, &rhsc); 4565 1.1 mrg process_all_all_constraints (lhsc, rhsc); 4566 1.1 mrg lhsc.truncate (0); 4567 1.1 mrg } 4568 1.1 mrg get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc); 4569 1.1 mrg do_deref (&lhsc); 4570 1.1 mrg if (flag_delete_null_pointer_checks 4571 1.1 mrg && integer_zerop (gimple_call_arg (t, 1))) 4572 1.1 mrg { 4573 1.1 mrg ac.type = ADDRESSOF; 4574 1.1 mrg ac.var = nothing_id; 4575 1.1 mrg } 4576 1.1 mrg else 4577 1.1 mrg { 4578 1.1 mrg ac.type = SCALAR; 4579 1.1 mrg ac.var = integer_id; 4580 1.1 mrg } 4581 1.1 mrg ac.offset = 0; 4582 1.1 mrg FOR_EACH_VEC_ELT (lhsc, i, lhsp) 4583 1.1 mrg process_constraint (new_constraint (*lhsp, ac)); 4584 1.1 mrg return true; 4585 1.1 mrg } 4586 1.1 mrg case BUILT_IN_STACK_SAVE: 4587 1.1 mrg case BUILT_IN_STACK_RESTORE: 4588 1.1 mrg /* Nothing interesting happens. */ 4589 1.1 mrg return true; 4590 1.1 mrg case BUILT_IN_ALLOCA: 4591 1.1 mrg case BUILT_IN_ALLOCA_WITH_ALIGN: 4592 1.1 mrg case BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX: 4593 1.1 mrg { 4594 1.1 mrg tree ptr = gimple_call_lhs (t); 4595 1.1 mrg if (ptr == NULL_TREE) 4596 1.1 mrg return true; 4597 1.1 mrg get_constraint_for (ptr, &lhsc); 4598 1.1 mrg varinfo_t vi = make_heapvar ("HEAP", true); 4599 1.1 mrg /* Alloca storage is never global. To exempt it from escaped 4600 1.1 mrg handling make it a non-heap var. */ 4601 1.1 mrg DECL_EXTERNAL (vi->decl) = 0; 4602 1.1 mrg vi->is_global_var = 0; 4603 1.1 mrg vi->is_heap_var = 0; 4604 1.1 mrg struct constraint_expr tmpc; 4605 1.1 mrg tmpc.var = vi->id; 4606 1.1 mrg tmpc.offset = 0; 4607 1.1 mrg tmpc.type = ADDRESSOF; 4608 1.1 mrg rhsc.safe_push (tmpc); 4609 1.1 mrg process_all_all_constraints (lhsc, rhsc); 4610 1.1 mrg return true; 4611 1.1 mrg } 4612 1.1 mrg case BUILT_IN_POSIX_MEMALIGN: 4613 1.1 mrg { 4614 1.1 mrg tree ptrptr = gimple_call_arg (t, 0); 4615 1.1 mrg get_constraint_for (ptrptr, &lhsc); 4616 1.1 mrg do_deref (&lhsc); 4617 1.1 mrg varinfo_t vi = make_heapvar ("HEAP", true); 4618 1.1 mrg /* We are marking allocated storage local, we deal with it becoming 4619 1.1 mrg global by escaping and setting of vars_contains_escaped_heap. */ 4620 1.1 mrg DECL_EXTERNAL (vi->decl) = 0; 4621 1.1 mrg vi->is_global_var = 0; 4622 1.1 mrg struct constraint_expr tmpc; 4623 1.1 mrg tmpc.var = vi->id; 4624 1.1 mrg tmpc.offset = 0; 4625 1.1 mrg tmpc.type = ADDRESSOF; 4626 1.1 mrg rhsc.safe_push (tmpc); 4627 1.1 mrg process_all_all_constraints (lhsc, rhsc); 4628 1.1 mrg return true; 4629 1.1 mrg } 4630 1.1 mrg case BUILT_IN_ASSUME_ALIGNED: 4631 1.1 mrg { 4632 1.1 mrg tree res = gimple_call_lhs (t); 4633 1.1 mrg tree dest = gimple_call_arg (t, 0); 4634 1.1 mrg if (res != NULL_TREE) 4635 1.1 mrg { 4636 1.1 mrg get_constraint_for (res, &lhsc); 4637 1.1 mrg get_constraint_for (dest, &rhsc); 4638 1.1 mrg process_all_all_constraints (lhsc, rhsc); 4639 1.1 mrg } 4640 1.1 mrg return true; 4641 1.1 mrg } 4642 1.1 mrg /* All the following functions do not return pointers, do not 4643 1.1 mrg modify the points-to sets of memory reachable from their 4644 1.1 mrg arguments and do not add to the ESCAPED solution. */ 4645 1.1 mrg case BUILT_IN_SINCOS: 4646 1.1 mrg case BUILT_IN_SINCOSF: 4647 1.1 mrg case BUILT_IN_SINCOSL: 4648 1.1 mrg case BUILT_IN_FREXP: 4649 1.1 mrg case BUILT_IN_FREXPF: 4650 1.1 mrg case BUILT_IN_FREXPL: 4651 1.1 mrg case BUILT_IN_GAMMA_R: 4652 1.1 mrg case BUILT_IN_GAMMAF_R: 4653 1.1 mrg case BUILT_IN_GAMMAL_R: 4654 1.1 mrg case BUILT_IN_LGAMMA_R: 4655 1.1 mrg case BUILT_IN_LGAMMAF_R: 4656 1.1 mrg case BUILT_IN_LGAMMAL_R: 4657 1.1 mrg case BUILT_IN_MODF: 4658 1.1 mrg case BUILT_IN_MODFF: 4659 1.1 mrg case BUILT_IN_MODFL: 4660 1.1 mrg case BUILT_IN_REMQUO: 4661 1.1 mrg case BUILT_IN_REMQUOF: 4662 1.1 mrg case BUILT_IN_REMQUOL: 4663 1.1 mrg case BUILT_IN_FREE: 4664 1.1 mrg return true; 4665 1.1 mrg case BUILT_IN_STRDUP: 4666 1.1 mrg case BUILT_IN_STRNDUP: 4667 1.1 mrg case BUILT_IN_REALLOC: 4668 1.1 mrg if (gimple_call_lhs (t)) 4669 1.1 mrg { 4670 1.1 mrg auto_vec<ce_s> rhsc; 4671 1.1 mrg handle_lhs_call (t, gimple_call_lhs (t), 4672 1.1 mrg gimple_call_return_flags (t) | ERF_NOALIAS, 4673 1.1 mrg rhsc, fndecl); 4674 1.1 mrg get_constraint_for_ptr_offset (gimple_call_lhs (t), 4675 1.1 mrg NULL_TREE, &lhsc); 4676 1.1 mrg get_constraint_for_ptr_offset (gimple_call_arg (t, 0), 4677 1.1 mrg NULL_TREE, &rhsc); 4678 1.1 mrg do_deref (&lhsc); 4679 1.1 mrg do_deref (&rhsc); 4680 1.1 mrg process_all_all_constraints (lhsc, rhsc); 4681 1.1 mrg lhsc.truncate (0); 4682 1.1 mrg rhsc.truncate (0); 4683 1.1 mrg /* For realloc the resulting pointer can be equal to the 4684 1.1 mrg argument as well. But only doing this wouldn't be 4685 1.1 mrg correct because with ptr == 0 realloc behaves like malloc. */ 4686 1.1 mrg if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_REALLOC) 4687 1.1 mrg { 4688 1.1 mrg get_constraint_for (gimple_call_lhs (t), &lhsc); 4689 1.1 mrg get_constraint_for (gimple_call_arg (t, 0), &rhsc); 4690 1.1 mrg process_all_all_constraints (lhsc, rhsc); 4691 1.1 mrg } 4692 1.1 mrg return true; 4693 1.1 mrg } 4694 1.1 mrg break; 4695 1.1 mrg /* String / character search functions return a pointer into the 4696 1.1 mrg source string or NULL. */ 4697 1.1 mrg case BUILT_IN_INDEX: 4698 1.1 mrg case BUILT_IN_STRCHR: 4699 1.1 mrg case BUILT_IN_STRRCHR: 4700 1.1 mrg case BUILT_IN_MEMCHR: 4701 1.1 mrg case BUILT_IN_STRSTR: 4702 1.1 mrg case BUILT_IN_STRPBRK: 4703 1.1 mrg if (gimple_call_lhs (t)) 4704 1.1 mrg { 4705 1.1 mrg tree src = gimple_call_arg (t, 0); 4706 1.1 mrg get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc); 4707 1.1 mrg constraint_expr nul; 4708 1.1 mrg nul.var = nothing_id; 4709 1.1 mrg nul.offset = 0; 4710 1.1 mrg nul.type = ADDRESSOF; 4711 1.1 mrg rhsc.safe_push (nul); 4712 1.1 mrg get_constraint_for (gimple_call_lhs (t), &lhsc); 4713 1.1 mrg process_all_all_constraints (lhsc, rhsc); 4714 1.1 mrg } 4715 1.1 mrg return true; 4716 1.1 mrg /* Pure functions that return something not based on any object and 4717 1.1 mrg that use the memory pointed to by their arguments (but not 4718 1.1 mrg transitively). */ 4719 1.1 mrg case BUILT_IN_STRCMP: 4720 1.1 mrg case BUILT_IN_STRCMP_EQ: 4721 1.1 mrg case BUILT_IN_STRNCMP: 4722 1.1 mrg case BUILT_IN_STRNCMP_EQ: 4723 1.1 mrg case BUILT_IN_STRCASECMP: 4724 1.1 mrg case BUILT_IN_STRNCASECMP: 4725 1.1 mrg case BUILT_IN_MEMCMP: 4726 1.1 mrg case BUILT_IN_BCMP: 4727 1.1 mrg case BUILT_IN_STRSPN: 4728 1.1 mrg case BUILT_IN_STRCSPN: 4729 1.1 mrg { 4730 1.1 mrg varinfo_t uses = get_call_use_vi (t); 4731 1.1 mrg make_any_offset_constraints (uses); 4732 1.1 mrg make_constraint_to (uses->id, gimple_call_arg (t, 0)); 4733 1.1 mrg make_constraint_to (uses->id, gimple_call_arg (t, 1)); 4734 1.1 mrg /* No constraints are necessary for the return value. */ 4735 1.1 mrg return true; 4736 1.1 mrg } 4737 1.1 mrg case BUILT_IN_STRLEN: 4738 1.1 mrg { 4739 1.1 mrg varinfo_t uses = get_call_use_vi (t); 4740 1.1 mrg make_any_offset_constraints (uses); 4741 1.1 mrg make_constraint_to (uses->id, gimple_call_arg (t, 0)); 4742 1.1 mrg /* No constraints are necessary for the return value. */ 4743 1.1 mrg return true; 4744 1.1 mrg } 4745 1.1 mrg case BUILT_IN_OBJECT_SIZE: 4746 1.1 mrg case BUILT_IN_CONSTANT_P: 4747 1.1 mrg { 4748 1.1 mrg /* No constraints are necessary for the return value or the 4749 1.1 mrg arguments. */ 4750 1.1 mrg return true; 4751 1.1 mrg } 4752 1.1 mrg /* Trampolines are special - they set up passing the static 4753 1.1 mrg frame. */ 4754 1.1 mrg case BUILT_IN_INIT_TRAMPOLINE: 4755 1.1 mrg { 4756 1.1 mrg tree tramp = gimple_call_arg (t, 0); 4757 1.1 mrg tree nfunc = gimple_call_arg (t, 1); 4758 1.1 mrg tree frame = gimple_call_arg (t, 2); 4759 1.1 mrg unsigned i; 4760 1.1 mrg struct constraint_expr lhs, *rhsp; 4761 1.1 mrg if (in_ipa_mode) 4762 1.1 mrg { 4763 1.1 mrg varinfo_t nfi = NULL; 4764 1.1 mrg gcc_assert (TREE_CODE (nfunc) == ADDR_EXPR); 4765 1.1 mrg nfi = lookup_vi_for_tree (TREE_OPERAND (nfunc, 0)); 4766 1.1 mrg if (nfi) 4767 1.1 mrg { 4768 1.1 mrg lhs = get_function_part_constraint (nfi, fi_static_chain); 4769 1.1 mrg get_constraint_for (frame, &rhsc); 4770 1.1 mrg FOR_EACH_VEC_ELT (rhsc, i, rhsp) 4771 1.1 mrg process_constraint (new_constraint (lhs, *rhsp)); 4772 1.1 mrg rhsc.truncate (0); 4773 1.1 mrg 4774 1.1 mrg /* Make the frame point to the function for 4775 1.1 mrg the trampoline adjustment call. */ 4776 1.1 mrg get_constraint_for (tramp, &lhsc); 4777 1.1 mrg do_deref (&lhsc); 4778 1.1 mrg get_constraint_for (nfunc, &rhsc); 4779 1.1 mrg process_all_all_constraints (lhsc, rhsc); 4780 1.1 mrg 4781 1.1 mrg return true; 4782 1.1 mrg } 4783 1.1 mrg } 4784 1.1 mrg /* Else fallthru to generic handling which will let 4785 1.1 mrg the frame escape. */ 4786 1.1 mrg break; 4787 1.1 mrg } 4788 1.1 mrg case BUILT_IN_ADJUST_TRAMPOLINE: 4789 1.1 mrg { 4790 1.1 mrg tree tramp = gimple_call_arg (t, 0); 4791 1.1 mrg tree res = gimple_call_lhs (t); 4792 1.1 mrg if (in_ipa_mode && res) 4793 1.1 mrg { 4794 1.1 mrg get_constraint_for (res, &lhsc); 4795 1.1 mrg get_constraint_for (tramp, &rhsc); 4796 1.1 mrg do_deref (&rhsc); 4797 1.1 mrg process_all_all_constraints (lhsc, rhsc); 4798 1.1 mrg } 4799 1.1 mrg return true; 4800 1.1 mrg } 4801 1.1 mrg CASE_BUILT_IN_TM_STORE (1): 4802 1.1 mrg CASE_BUILT_IN_TM_STORE (2): 4803 1.1 mrg CASE_BUILT_IN_TM_STORE (4): 4804 1.1 mrg CASE_BUILT_IN_TM_STORE (8): 4805 1.1 mrg CASE_BUILT_IN_TM_STORE (FLOAT): 4806 1.1 mrg CASE_BUILT_IN_TM_STORE (DOUBLE): 4807 1.1 mrg CASE_BUILT_IN_TM_STORE (LDOUBLE): 4808 1.1 mrg CASE_BUILT_IN_TM_STORE (M64): 4809 1.1 mrg CASE_BUILT_IN_TM_STORE (M128): 4810 1.1 mrg CASE_BUILT_IN_TM_STORE (M256): 4811 1.1 mrg { 4812 1.1 mrg tree addr = gimple_call_arg (t, 0); 4813 1.1 mrg tree src = gimple_call_arg (t, 1); 4814 1.1 mrg 4815 1.1 mrg get_constraint_for (addr, &lhsc); 4816 1.1 mrg do_deref (&lhsc); 4817 1.1 mrg get_constraint_for (src, &rhsc); 4818 1.1 mrg process_all_all_constraints (lhsc, rhsc); 4819 1.1 mrg return true; 4820 1.1 mrg } 4821 1.1 mrg CASE_BUILT_IN_TM_LOAD (1): 4822 1.1 mrg CASE_BUILT_IN_TM_LOAD (2): 4823 1.1 mrg CASE_BUILT_IN_TM_LOAD (4): 4824 1.1 mrg CASE_BUILT_IN_TM_LOAD (8): 4825 1.1 mrg CASE_BUILT_IN_TM_LOAD (FLOAT): 4826 1.1 mrg CASE_BUILT_IN_TM_LOAD (DOUBLE): 4827 1.1 mrg CASE_BUILT_IN_TM_LOAD (LDOUBLE): 4828 1.1 mrg CASE_BUILT_IN_TM_LOAD (M64): 4829 1.1 mrg CASE_BUILT_IN_TM_LOAD (M128): 4830 1.1 mrg CASE_BUILT_IN_TM_LOAD (M256): 4831 1.1 mrg { 4832 1.1 mrg tree dest = gimple_call_lhs (t); 4833 1.1 mrg tree addr = gimple_call_arg (t, 0); 4834 1.1 mrg 4835 1.1 mrg get_constraint_for (dest, &lhsc); 4836 1.1 mrg get_constraint_for (addr, &rhsc); 4837 1.1 mrg do_deref (&rhsc); 4838 1.1 mrg process_all_all_constraints (lhsc, rhsc); 4839 1.1 mrg return true; 4840 1.1 mrg } 4841 1.1 mrg /* Variadic argument handling needs to be handled in IPA 4842 1.1 mrg mode as well. */ 4843 1.1 mrg case BUILT_IN_VA_START: 4844 1.1 mrg { 4845 1.1 mrg tree valist = gimple_call_arg (t, 0); 4846 1.1 mrg struct constraint_expr rhs, *lhsp; 4847 1.1 mrg unsigned i; 4848 1.1 mrg get_constraint_for_ptr_offset (valist, NULL_TREE, &lhsc); 4849 1.1 mrg do_deref (&lhsc); 4850 1.1 mrg /* The va_list gets access to pointers in variadic 4851 1.1 mrg arguments. Which we know in the case of IPA analysis 4852 1.1 mrg and otherwise are just all nonlocal variables. */ 4853 1.1 mrg if (in_ipa_mode) 4854 1.1 mrg { 4855 1.1 mrg fi = lookup_vi_for_tree (fn->decl); 4856 1.1 mrg rhs = get_function_part_constraint (fi, ~0); 4857 1.1 mrg rhs.type = ADDRESSOF; 4858 1.1 mrg } 4859 1.1 mrg else 4860 1.1 mrg { 4861 1.1 mrg rhs.var = nonlocal_id; 4862 1.1 mrg rhs.type = ADDRESSOF; 4863 1.1 mrg rhs.offset = 0; 4864 1.1 mrg } 4865 1.1 mrg FOR_EACH_VEC_ELT (lhsc, i, lhsp) 4866 1.1 mrg process_constraint (new_constraint (*lhsp, rhs)); 4867 1.1 mrg /* va_list is clobbered. */ 4868 1.1 mrg make_constraint_to (get_call_clobber_vi (t)->id, valist); 4869 1.1 mrg return true; 4870 1.1 mrg } 4871 1.1 mrg /* va_end doesn't have any effect that matters. */ 4872 1.1 mrg case BUILT_IN_VA_END: 4873 1.1 mrg return true; 4874 1.1 mrg /* Alternate return. Simply give up for now. */ 4875 1.1 mrg case BUILT_IN_RETURN: 4876 1.1 mrg { 4877 1.1 mrg fi = NULL; 4878 1.1 mrg if (!in_ipa_mode 4879 1.1 mrg || !(fi = get_vi_for_tree (fn->decl))) 4880 1.1 mrg make_constraint_from (get_varinfo (escaped_id), anything_id); 4881 1.1 mrg else if (in_ipa_mode 4882 1.1 mrg && fi != NULL) 4883 1.1 mrg { 4884 1.1 mrg struct constraint_expr lhs, rhs; 4885 1.1 mrg lhs = get_function_part_constraint (fi, fi_result); 4886 1.1 mrg rhs.var = anything_id; 4887 1.1 mrg rhs.offset = 0; 4888 1.1 mrg rhs.type = SCALAR; 4889 1.1 mrg process_constraint (new_constraint (lhs, rhs)); 4890 1.1 mrg } 4891 1.1 mrg return true; 4892 1.1 mrg } 4893 1.1 mrg case BUILT_IN_GOMP_PARALLEL: 4894 1.1 mrg case BUILT_IN_GOACC_PARALLEL: 4895 1.1 mrg { 4896 1.1 mrg if (in_ipa_mode) 4897 1.1 mrg { 4898 1.1 mrg unsigned int fnpos, argpos; 4899 1.1 mrg switch (DECL_FUNCTION_CODE (fndecl)) 4900 1.1 mrg { 4901 1.1 mrg case BUILT_IN_GOMP_PARALLEL: 4902 1.1 mrg /* __builtin_GOMP_parallel (fn, data, num_threads, flags). */ 4903 1.1 mrg fnpos = 0; 4904 1.1 mrg argpos = 1; 4905 1.1 mrg break; 4906 1.1 mrg case BUILT_IN_GOACC_PARALLEL: 4907 1.1 mrg /* __builtin_GOACC_parallel (flags_m, fn, mapnum, hostaddrs, 4908 1.1 mrg sizes, kinds, ...). */ 4909 1.1 mrg fnpos = 1; 4910 1.1 mrg argpos = 3; 4911 1.1 mrg break; 4912 1.1 mrg default: 4913 1.1 mrg gcc_unreachable (); 4914 1.1 mrg } 4915 1.1 mrg 4916 1.1 mrg tree fnarg = gimple_call_arg (t, fnpos); 4917 1.1 mrg gcc_assert (TREE_CODE (fnarg) == ADDR_EXPR); 4918 1.1 mrg tree fndecl = TREE_OPERAND (fnarg, 0); 4919 1.1 mrg if (fndecl_maybe_in_other_partition (fndecl)) 4920 1.1 mrg /* Fallthru to general call handling. */ 4921 1.1 mrg break; 4922 1.1 mrg 4923 1.1 mrg tree arg = gimple_call_arg (t, argpos); 4924 1.1 mrg 4925 1.1 mrg varinfo_t fi = get_vi_for_tree (fndecl); 4926 1.1 mrg find_func_aliases_for_call_arg (fi, 0, arg); 4927 1.1 mrg return true; 4928 1.1 mrg } 4929 1.1 mrg /* Else fallthru to generic call handling. */ 4930 1.1 mrg break; 4931 1.1 mrg } 4932 1.1 mrg /* printf-style functions may have hooks to set pointers to 4933 1.1 mrg point to somewhere into the generated string. Leave them 4934 1.1 mrg for a later exercise... */ 4935 1.1 mrg default: 4936 1.1 mrg /* Fallthru to general call handling. */; 4937 1.1 mrg } 4938 1.1 mrg 4939 1.1 mrg return false; 4940 1.1 mrg } 4941 1.1 mrg 4942 1.1 mrg /* Create constraints for the call T. */ 4943 1.1 mrg 4944 1.1 mrg static void 4945 1.1 mrg find_func_aliases_for_call (struct function *fn, gcall *t) 4946 1.1 mrg { 4947 1.1 mrg tree fndecl = gimple_call_fndecl (t); 4948 1.1 mrg varinfo_t fi; 4949 1.1 mrg 4950 1.1 mrg if (fndecl != NULL_TREE 4951 1.1 mrg && fndecl_built_in_p (fndecl) 4952 1.1 mrg && find_func_aliases_for_builtin_call (fn, t)) 4953 1.1 mrg return; 4954 1.1 mrg 4955 1.1 mrg if (gimple_call_internal_p (t, IFN_DEFERRED_INIT)) 4956 1.1 mrg return; 4957 1.1 mrg 4958 1.1 mrg fi = get_fi_for_callee (t); 4959 1.1 mrg if (!in_ipa_mode 4960 1.1 mrg || (fi->decl && fndecl && !fi->is_fn_info)) 4961 1.1 mrg { 4962 1.1 mrg auto_vec<ce_s, 16> rhsc; 4963 1.1 mrg int flags = gimple_call_flags (t); 4964 1.1 mrg 4965 1.1 mrg /* Const functions can return their arguments and addresses 4966 1.1 mrg of global memory but not of escaped memory. */ 4967 1.1 mrg if (flags & (ECF_CONST|ECF_NOVOPS)) 4968 1.1 mrg { 4969 1.1 mrg if (gimple_call_lhs (t)) 4970 1.1 mrg handle_rhs_call (t, &rhsc, implicit_const_eaf_flags, false, false); 4971 1.1 mrg } 4972 1.1 mrg /* Pure functions can return addresses in and of memory 4973 1.1 mrg reachable from their arguments, but they are not an escape 4974 1.1 mrg point for reachable memory of their arguments. */ 4975 1.1 mrg else if (flags & (ECF_PURE|ECF_LOOPING_CONST_OR_PURE)) 4976 1.1 mrg handle_rhs_call (t, &rhsc, implicit_pure_eaf_flags, false, true); 4977 1.1 mrg /* If the call is to a replaceable operator delete and results 4978 1.1 mrg from a delete expression as opposed to a direct call to 4979 1.1 mrg such operator, then the effects for PTA (in particular 4980 1.1 mrg the escaping of the pointer) can be ignored. */ 4981 1.1 mrg else if (fndecl 4982 1.1 mrg && DECL_IS_OPERATOR_DELETE_P (fndecl) 4983 1.1 mrg && gimple_call_from_new_or_delete (t)) 4984 1.1 mrg ; 4985 1.1 mrg else 4986 1.1 mrg handle_rhs_call (t, &rhsc, 0, true, true); 4987 1.1 mrg if (gimple_call_lhs (t)) 4988 1.1 mrg handle_lhs_call (t, gimple_call_lhs (t), 4989 1.1 mrg gimple_call_return_flags (t), rhsc, fndecl); 4990 1.1 mrg } 4991 1.1 mrg else 4992 1.1 mrg { 4993 1.1 mrg auto_vec<ce_s, 2> rhsc; 4994 1.1 mrg tree lhsop; 4995 1.1 mrg unsigned j; 4996 1.1 mrg 4997 1.1 mrg /* Assign all the passed arguments to the appropriate incoming 4998 1.1 mrg parameters of the function. */ 4999 1.1 mrg for (j = 0; j < gimple_call_num_args (t); j++) 5000 1.1 mrg { 5001 1.1 mrg tree arg = gimple_call_arg (t, j); 5002 1.1 mrg find_func_aliases_for_call_arg (fi, j, arg); 5003 1.1 mrg } 5004 1.1 mrg 5005 1.1 mrg /* If we are returning a value, assign it to the result. */ 5006 1.1 mrg lhsop = gimple_call_lhs (t); 5007 1.1 mrg if (lhsop) 5008 1.1 mrg { 5009 1.1 mrg auto_vec<ce_s, 2> lhsc; 5010 1.1 mrg struct constraint_expr rhs; 5011 1.1 mrg struct constraint_expr *lhsp; 5012 1.1 mrg bool aggr_p = aggregate_value_p (lhsop, gimple_call_fntype (t)); 5013 1.1 mrg 5014 1.1 mrg get_constraint_for (lhsop, &lhsc); 5015 1.1 mrg rhs = get_function_part_constraint (fi, fi_result); 5016 1.1 mrg if (aggr_p) 5017 1.1 mrg { 5018 1.1 mrg auto_vec<ce_s, 2> tem; 5019 1.1 mrg tem.quick_push (rhs); 5020 1.1 mrg do_deref (&tem); 5021 1.1 mrg gcc_checking_assert (tem.length () == 1); 5022 1.1 mrg rhs = tem[0]; 5023 1.1 mrg } 5024 1.1 mrg FOR_EACH_VEC_ELT (lhsc, j, lhsp) 5025 1.1 mrg process_constraint (new_constraint (*lhsp, rhs)); 5026 1.1 mrg 5027 1.1 mrg /* If we pass the result decl by reference, honor that. */ 5028 1.1 mrg if (aggr_p) 5029 1.1 mrg { 5030 1.1 mrg struct constraint_expr lhs; 5031 1.1 mrg struct constraint_expr *rhsp; 5032 1.1 mrg 5033 1.1 mrg get_constraint_for_address_of (lhsop, &rhsc); 5034 1.1 mrg lhs = get_function_part_constraint (fi, fi_result); 5035 1.1 mrg FOR_EACH_VEC_ELT (rhsc, j, rhsp) 5036 1.1 mrg process_constraint (new_constraint (lhs, *rhsp)); 5037 1.1 mrg rhsc.truncate (0); 5038 1.1 mrg } 5039 1.1 mrg } 5040 1.1 mrg 5041 1.1 mrg /* If we use a static chain, pass it along. */ 5042 1.1 mrg if (gimple_call_chain (t)) 5043 1.1 mrg { 5044 1.1 mrg struct constraint_expr lhs; 5045 1.1 mrg struct constraint_expr *rhsp; 5046 1.1 mrg 5047 1.1 mrg get_constraint_for (gimple_call_chain (t), &rhsc); 5048 1.1 mrg lhs = get_function_part_constraint (fi, fi_static_chain); 5049 1.1 mrg FOR_EACH_VEC_ELT (rhsc, j, rhsp) 5050 1.1 mrg process_constraint (new_constraint (lhs, *rhsp)); 5051 1.1 mrg } 5052 1.1 mrg } 5053 1.1 mrg } 5054 1.1 mrg 5055 1.1 mrg /* Walk statement T setting up aliasing constraints according to the 5056 1.1 mrg references found in T. This function is the main part of the 5057 1.1 mrg constraint builder. AI points to auxiliary alias information used 5058 1.1 mrg when building alias sets and computing alias grouping heuristics. */ 5059 1.1 mrg 5060 1.1 mrg static void 5061 1.1 mrg find_func_aliases (struct function *fn, gimple *origt) 5062 1.1 mrg { 5063 1.1 mrg gimple *t = origt; 5064 1.1 mrg auto_vec<ce_s, 16> lhsc; 5065 1.1 mrg auto_vec<ce_s, 16> rhsc; 5066 1.1 mrg varinfo_t fi; 5067 1.1 mrg 5068 1.1 mrg /* Now build constraints expressions. */ 5069 1.1 mrg if (gimple_code (t) == GIMPLE_PHI) 5070 1.1 mrg { 5071 1.1 mrg /* For a phi node, assign all the arguments to 5072 1.1 mrg the result. */ 5073 1.1 mrg get_constraint_for (gimple_phi_result (t), &lhsc); 5074 1.1 mrg for (unsigned i = 0; i < gimple_phi_num_args (t); i++) 5075 1.1 mrg { 5076 1.1 mrg get_constraint_for_rhs (gimple_phi_arg_def (t, i), &rhsc); 5077 1.1 mrg process_all_all_constraints (lhsc, rhsc); 5078 1.1 mrg rhsc.truncate (0); 5079 1.1 mrg } 5080 1.1 mrg } 5081 1.1 mrg /* In IPA mode, we need to generate constraints to pass call 5082 1.1 mrg arguments through their calls. There are two cases, 5083 1.1 mrg either a GIMPLE_CALL returning a value, or just a plain 5084 1.1 mrg GIMPLE_CALL when we are not. 5085 1.1 mrg 5086 1.1 mrg In non-ipa mode, we need to generate constraints for each 5087 1.1 mrg pointer passed by address. */ 5088 1.1 mrg else if (is_gimple_call (t)) 5089 1.1 mrg find_func_aliases_for_call (fn, as_a <gcall *> (t)); 5090 1.1 mrg 5091 1.1 mrg /* Otherwise, just a regular assignment statement. Only care about 5092 1.1 mrg operations with pointer result, others are dealt with as escape 5093 1.1 mrg points if they have pointer operands. */ 5094 1.1 mrg else if (is_gimple_assign (t)) 5095 1.1 mrg { 5096 1.1 mrg /* Otherwise, just a regular assignment statement. */ 5097 1.1 mrg tree lhsop = gimple_assign_lhs (t); 5098 1.1 mrg tree rhsop = (gimple_num_ops (t) == 2) ? gimple_assign_rhs1 (t) : NULL; 5099 1.1 mrg 5100 1.1 mrg if (rhsop && TREE_CLOBBER_P (rhsop)) 5101 1.1 mrg /* Ignore clobbers, they don't actually store anything into 5102 1.1 mrg the LHS. */ 5103 1.1 mrg ; 5104 1.1 mrg else if (rhsop && AGGREGATE_TYPE_P (TREE_TYPE (lhsop))) 5105 1.1 mrg do_structure_copy (lhsop, rhsop); 5106 1.1 mrg else 5107 1.1 mrg { 5108 1.1 mrg enum tree_code code = gimple_assign_rhs_code (t); 5109 1.1 mrg 5110 1.1 mrg get_constraint_for (lhsop, &lhsc); 5111 1.1 mrg 5112 1.1 mrg if (code == POINTER_PLUS_EXPR) 5113 1.1 mrg get_constraint_for_ptr_offset (gimple_assign_rhs1 (t), 5114 1.1 mrg gimple_assign_rhs2 (t), &rhsc); 5115 1.1 mrg else if (code == POINTER_DIFF_EXPR) 5116 1.1 mrg /* The result is not a pointer (part). */ 5117 1.1 mrg ; 5118 1.1 mrg else if (code == BIT_AND_EXPR 5119 1.1 mrg && TREE_CODE (gimple_assign_rhs2 (t)) == INTEGER_CST) 5120 1.1 mrg { 5121 1.1 mrg /* Aligning a pointer via a BIT_AND_EXPR is offsetting 5122 1.1 mrg the pointer. Handle it by offsetting it by UNKNOWN. */ 5123 1.1 mrg get_constraint_for_ptr_offset (gimple_assign_rhs1 (t), 5124 1.1 mrg NULL_TREE, &rhsc); 5125 1.1 mrg } 5126 1.1 mrg else if (code == TRUNC_DIV_EXPR 5127 1.1 mrg || code == CEIL_DIV_EXPR 5128 1.1 mrg || code == FLOOR_DIV_EXPR 5129 1.1 mrg || code == ROUND_DIV_EXPR 5130 1.1 mrg || code == EXACT_DIV_EXPR 5131 1.1 mrg || code == TRUNC_MOD_EXPR 5132 1.1 mrg || code == CEIL_MOD_EXPR 5133 1.1 mrg || code == FLOOR_MOD_EXPR 5134 1.1 mrg || code == ROUND_MOD_EXPR) 5135 1.1 mrg /* Division and modulo transfer the pointer from the LHS. */ 5136 1.1 mrg get_constraint_for_ptr_offset (gimple_assign_rhs1 (t), 5137 1.1 mrg NULL_TREE, &rhsc); 5138 1.1 mrg else if (CONVERT_EXPR_CODE_P (code) 5139 1.1 mrg || gimple_assign_single_p (t)) 5140 1.1 mrg /* See through conversions, single RHS are handled by 5141 1.1 mrg get_constraint_for_rhs. */ 5142 1.1 mrg get_constraint_for_rhs (rhsop, &rhsc); 5143 1.1 mrg else if (code == COND_EXPR) 5144 1.1 mrg { 5145 1.1 mrg /* The result is a merge of both COND_EXPR arms. */ 5146 1.1 mrg auto_vec<ce_s, 2> tmp; 5147 1.1 mrg struct constraint_expr *rhsp; 5148 1.1 mrg unsigned i; 5149 1.1 mrg get_constraint_for_rhs (gimple_assign_rhs2 (t), &rhsc); 5150 1.1 mrg get_constraint_for_rhs (gimple_assign_rhs3 (t), &tmp); 5151 1.1 mrg FOR_EACH_VEC_ELT (tmp, i, rhsp) 5152 1.1 mrg rhsc.safe_push (*rhsp); 5153 1.1 mrg } 5154 1.1 mrg else if (truth_value_p (code)) 5155 1.1 mrg /* Truth value results are not pointer (parts). Or at least 5156 1.1 mrg very unreasonable obfuscation of a part. */ 5157 1.1 mrg ; 5158 1.1 mrg else 5159 1.1 mrg { 5160 1.1 mrg /* All other operations are possibly offsetting merges. */ 5161 1.1 mrg auto_vec<ce_s, 4> tmp; 5162 1.1 mrg struct constraint_expr *rhsp; 5163 1.1 mrg unsigned i, j; 5164 1.1 mrg get_constraint_for_ptr_offset (gimple_assign_rhs1 (t), 5165 1.1 mrg NULL_TREE, &rhsc); 5166 1.1 mrg for (i = 2; i < gimple_num_ops (t); ++i) 5167 1.1 mrg { 5168 1.1 mrg get_constraint_for_ptr_offset (gimple_op (t, i), 5169 1.1 mrg NULL_TREE, &tmp); 5170 1.1 mrg FOR_EACH_VEC_ELT (tmp, j, rhsp) 5171 1.1 mrg rhsc.safe_push (*rhsp); 5172 1.1 mrg tmp.truncate (0); 5173 1.1 mrg } 5174 1.1 mrg } 5175 1.1 mrg process_all_all_constraints (lhsc, rhsc); 5176 1.1 mrg } 5177 1.1 mrg /* If there is a store to a global variable the rhs escapes. */ 5178 1.1 mrg if ((lhsop = get_base_address (lhsop)) != NULL_TREE 5179 1.1 mrg && DECL_P (lhsop)) 5180 1.1 mrg { 5181 1.1 mrg varinfo_t vi = get_vi_for_tree (lhsop); 5182 1.1 mrg if ((! in_ipa_mode && vi->is_global_var) 5183 1.1 mrg || vi->is_ipa_escape_point) 5184 1.1 mrg make_escape_constraint (rhsop); 5185 1.1 mrg } 5186 1.1 mrg } 5187 1.1 mrg /* Handle escapes through return. */ 5188 1.1 mrg else if (gimple_code (t) == GIMPLE_RETURN 5189 1.1 mrg && gimple_return_retval (as_a <greturn *> (t)) != NULL_TREE) 5190 1.1 mrg { 5191 1.1 mrg greturn *return_stmt = as_a <greturn *> (t); 5192 1.1 mrg fi = NULL; 5193 1.1 mrg if (!in_ipa_mode 5194 1.1 mrg && SSA_VAR_P (gimple_return_retval (return_stmt))) 5195 1.1 mrg { 5196 1.1 mrg /* We handle simple returns by post-processing the solutions. */ 5197 1.1 mrg ; 5198 1.1 mrg } 5199 1.1 mrg if (!(fi = get_vi_for_tree (fn->decl))) 5200 1.1 mrg make_escape_constraint (gimple_return_retval (return_stmt)); 5201 1.1 mrg else if (in_ipa_mode) 5202 1.1 mrg { 5203 1.1 mrg struct constraint_expr lhs ; 5204 1.1 mrg struct constraint_expr *rhsp; 5205 1.1 mrg unsigned i; 5206 1.1 mrg 5207 1.1 mrg lhs = get_function_part_constraint (fi, fi_result); 5208 1.1 mrg get_constraint_for_rhs (gimple_return_retval (return_stmt), &rhsc); 5209 1.1 mrg FOR_EACH_VEC_ELT (rhsc, i, rhsp) 5210 1.1 mrg process_constraint (new_constraint (lhs, *rhsp)); 5211 1.1 mrg } 5212 1.1 mrg } 5213 1.1 mrg /* Handle asms conservatively by adding escape constraints to everything. */ 5214 1.1 mrg else if (gasm *asm_stmt = dyn_cast <gasm *> (t)) 5215 1.1 mrg { 5216 1.1 mrg unsigned i, noutputs; 5217 1.1 mrg const char **oconstraints; 5218 1.1 mrg const char *constraint; 5219 1.1 mrg bool allows_mem, allows_reg, is_inout; 5220 1.1 mrg 5221 1.1 mrg noutputs = gimple_asm_noutputs (asm_stmt); 5222 1.1 mrg oconstraints = XALLOCAVEC (const char *, noutputs); 5223 1.1 mrg 5224 1.1 mrg for (i = 0; i < noutputs; ++i) 5225 1.1 mrg { 5226 1.1 mrg tree link = gimple_asm_output_op (asm_stmt, i); 5227 1.1 mrg tree op = TREE_VALUE (link); 5228 1.1 mrg 5229 1.1 mrg constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); 5230 1.1 mrg oconstraints[i] = constraint; 5231 1.1 mrg parse_output_constraint (&constraint, i, 0, 0, &allows_mem, 5232 1.1 mrg &allows_reg, &is_inout); 5233 1.1 mrg 5234 1.1 mrg /* A memory constraint makes the address of the operand escape. */ 5235 1.1 mrg if (!allows_reg && allows_mem) 5236 1.1 mrg make_escape_constraint (build_fold_addr_expr (op)); 5237 1.1 mrg 5238 1.1 mrg /* The asm may read global memory, so outputs may point to 5239 1.1 mrg any global memory. */ 5240 1.1 mrg if (op) 5241 1.1 mrg { 5242 1.1 mrg auto_vec<ce_s, 2> lhsc; 5243 1.1 mrg struct constraint_expr rhsc, *lhsp; 5244 1.1 mrg unsigned j; 5245 1.1 mrg get_constraint_for (op, &lhsc); 5246 1.1 mrg rhsc.var = nonlocal_id; 5247 1.1 mrg rhsc.offset = 0; 5248 1.1 mrg rhsc.type = SCALAR; 5249 1.1 mrg FOR_EACH_VEC_ELT (lhsc, j, lhsp) 5250 1.1 mrg process_constraint (new_constraint (*lhsp, rhsc)); 5251 1.1 mrg } 5252 1.1 mrg } 5253 1.1 mrg for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i) 5254 1.1 mrg { 5255 1.1 mrg tree link = gimple_asm_input_op (asm_stmt, i); 5256 1.1 mrg tree op = TREE_VALUE (link); 5257 1.1 mrg 5258 1.1 mrg constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); 5259 1.1 mrg 5260 1.1 mrg parse_input_constraint (&constraint, 0, 0, noutputs, 0, oconstraints, 5261 1.1 mrg &allows_mem, &allows_reg); 5262 1.1 mrg 5263 1.1 mrg /* A memory constraint makes the address of the operand escape. */ 5264 1.1 mrg if (!allows_reg && allows_mem) 5265 1.1 mrg make_escape_constraint (build_fold_addr_expr (op)); 5266 1.1 mrg /* Strictly we'd only need the constraint to ESCAPED if 5267 1.1 mrg the asm clobbers memory, otherwise using something 5268 1.1 mrg along the lines of per-call clobbers/uses would be enough. */ 5269 1.1 mrg else if (op) 5270 1.1 mrg make_escape_constraint (op); 5271 1.1 mrg } 5272 1.1 mrg } 5273 1.1 mrg } 5274 1.1 mrg 5275 1.1 mrg 5276 1.1 mrg /* Create a constraint adding to the clobber set of FI the memory 5277 1.1 mrg pointed to by PTR. */ 5278 1.1 mrg 5279 1.1 mrg static void 5280 1.1 mrg process_ipa_clobber (varinfo_t fi, tree ptr) 5281 1.1 mrg { 5282 1.1 mrg vec<ce_s> ptrc = vNULL; 5283 1.1 mrg struct constraint_expr *c, lhs; 5284 1.1 mrg unsigned i; 5285 1.1 mrg get_constraint_for_rhs (ptr, &ptrc); 5286 1.1 mrg lhs = get_function_part_constraint (fi, fi_clobbers); 5287 1.1 mrg FOR_EACH_VEC_ELT (ptrc, i, c) 5288 1.1 mrg process_constraint (new_constraint (lhs, *c)); 5289 1.1 mrg ptrc.release (); 5290 1.1 mrg } 5291 1.1 mrg 5292 1.1 mrg /* Walk statement T setting up clobber and use constraints according to the 5293 1.1 mrg references found in T. This function is a main part of the 5294 1.1 mrg IPA constraint builder. */ 5295 1.1 mrg 5296 1.1 mrg static void 5297 1.1 mrg find_func_clobbers (struct function *fn, gimple *origt) 5298 1.1 mrg { 5299 1.1 mrg gimple *t = origt; 5300 1.1 mrg auto_vec<ce_s, 16> lhsc; 5301 1.1 mrg auto_vec<ce_s, 16> rhsc; 5302 1.1 mrg varinfo_t fi; 5303 1.1 mrg 5304 1.1 mrg /* Add constraints for clobbered/used in IPA mode. 5305 1.1 mrg We are not interested in what automatic variables are clobbered 5306 1.1 mrg or used as we only use the information in the caller to which 5307 1.1 mrg they do not escape. */ 5308 1.1 mrg gcc_assert (in_ipa_mode); 5309 1.1 mrg 5310 1.1 mrg /* If the stmt refers to memory in any way it better had a VUSE. */ 5311 1.1 mrg if (gimple_vuse (t) == NULL_TREE) 5312 1.1 mrg return; 5313 1.1 mrg 5314 1.1 mrg /* We'd better have function information for the current function. */ 5315 1.1 mrg fi = lookup_vi_for_tree (fn->decl); 5316 1.1 mrg gcc_assert (fi != NULL); 5317 1.1 mrg 5318 1.1 mrg /* Account for stores in assignments and calls. */ 5319 1.1 mrg if (gimple_vdef (t) != NULL_TREE 5320 1.1 mrg && gimple_has_lhs (t)) 5321 1.1 mrg { 5322 1.1 mrg tree lhs = gimple_get_lhs (t); 5323 1.1 mrg tree tem = lhs; 5324 1.1 mrg while (handled_component_p (tem)) 5325 1.1 mrg tem = TREE_OPERAND (tem, 0); 5326 1.1 mrg if ((DECL_P (tem) 5327 1.1 mrg && !auto_var_in_fn_p (tem, fn->decl)) 5328 1.1 mrg || INDIRECT_REF_P (tem) 5329 1.1 mrg || (TREE_CODE (tem) == MEM_REF 5330 1.1 mrg && !(TREE_CODE (TREE_OPERAND (tem, 0)) == ADDR_EXPR 5331 1.1 mrg && auto_var_in_fn_p 5332 1.1 mrg (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), fn->decl)))) 5333 1.1 mrg { 5334 1.1 mrg struct constraint_expr lhsc, *rhsp; 5335 1.1 mrg unsigned i; 5336 1.1 mrg lhsc = get_function_part_constraint (fi, fi_clobbers); 5337 1.1 mrg get_constraint_for_address_of (lhs, &rhsc); 5338 1.1 mrg FOR_EACH_VEC_ELT (rhsc, i, rhsp) 5339 1.1 mrg process_constraint (new_constraint (lhsc, *rhsp)); 5340 1.1 mrg rhsc.truncate (0); 5341 1.1 mrg } 5342 1.1 mrg } 5343 1.1 mrg 5344 1.1 mrg /* Account for uses in assigments and returns. */ 5345 1.1 mrg if (gimple_assign_single_p (t) 5346 1.1 mrg || (gimple_code (t) == GIMPLE_RETURN 5347 1.1 mrg && gimple_return_retval (as_a <greturn *> (t)) != NULL_TREE)) 5348 1.1 mrg { 5349 1.1 mrg tree rhs = (gimple_assign_single_p (t) 5350 1.1 mrg ? gimple_assign_rhs1 (t) 5351 1.1 mrg : gimple_return_retval (as_a <greturn *> (t))); 5352 1.1 mrg tree tem = rhs; 5353 1.1 mrg while (handled_component_p (tem)) 5354 1.1 mrg tem = TREE_OPERAND (tem, 0); 5355 1.1 mrg if ((DECL_P (tem) 5356 1.1 mrg && !auto_var_in_fn_p (tem, fn->decl)) 5357 1.1 mrg || INDIRECT_REF_P (tem) 5358 1.1 mrg || (TREE_CODE (tem) == MEM_REF 5359 1.1 mrg && !(TREE_CODE (TREE_OPERAND (tem, 0)) == ADDR_EXPR 5360 1.1 mrg && auto_var_in_fn_p 5361 1.1 mrg (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), fn->decl)))) 5362 1.1 mrg { 5363 1.1 mrg struct constraint_expr lhs, *rhsp; 5364 1.1 mrg unsigned i; 5365 1.1 mrg lhs = get_function_part_constraint (fi, fi_uses); 5366 1.1 mrg get_constraint_for_address_of (rhs, &rhsc); 5367 1.1 mrg FOR_EACH_VEC_ELT (rhsc, i, rhsp) 5368 1.1 mrg process_constraint (new_constraint (lhs, *rhsp)); 5369 1.1 mrg rhsc.truncate (0); 5370 1.1 mrg } 5371 1.1 mrg } 5372 1.1 mrg 5373 1.1 mrg if (gcall *call_stmt = dyn_cast <gcall *> (t)) 5374 1.1 mrg { 5375 1.1 mrg varinfo_t cfi = NULL; 5376 1.1 mrg tree decl = gimple_call_fndecl (t); 5377 1.1 mrg struct constraint_expr lhs, rhs; 5378 1.1 mrg unsigned i, j; 5379 1.1 mrg 5380 1.1 mrg /* For builtins we do not have separate function info. For those 5381 1.1 mrg we do not generate escapes for we have to generate clobbers/uses. */ 5382 1.1 mrg if (gimple_call_builtin_p (t, BUILT_IN_NORMAL)) 5383 1.1 mrg switch (DECL_FUNCTION_CODE (decl)) 5384 1.1 mrg { 5385 1.1 mrg /* The following functions use and clobber memory pointed to 5386 1.1 mrg by their arguments. */ 5387 1.1 mrg case BUILT_IN_STRCPY: 5388 1.1 mrg case BUILT_IN_STRNCPY: 5389 1.1 mrg case BUILT_IN_BCOPY: 5390 1.1 mrg case BUILT_IN_MEMCPY: 5391 1.1 mrg case BUILT_IN_MEMMOVE: 5392 1.1 mrg case BUILT_IN_MEMPCPY: 5393 1.1 mrg case BUILT_IN_STPCPY: 5394 1.1 mrg case BUILT_IN_STPNCPY: 5395 1.1 mrg case BUILT_IN_STRCAT: 5396 1.1 mrg case BUILT_IN_STRNCAT: 5397 1.1 mrg case BUILT_IN_STRCPY_CHK: 5398 1.1 mrg case BUILT_IN_STRNCPY_CHK: 5399 1.1 mrg case BUILT_IN_MEMCPY_CHK: 5400 1.1 mrg case BUILT_IN_MEMMOVE_CHK: 5401 1.1 mrg case BUILT_IN_MEMPCPY_CHK: 5402 1.1 mrg case BUILT_IN_STPCPY_CHK: 5403 1.1 mrg case BUILT_IN_STPNCPY_CHK: 5404 1.1 mrg case BUILT_IN_STRCAT_CHK: 5405 1.1 mrg case BUILT_IN_STRNCAT_CHK: 5406 1.1 mrg { 5407 1.1 mrg tree dest = gimple_call_arg (t, (DECL_FUNCTION_CODE (decl) 5408 1.1 mrg == BUILT_IN_BCOPY ? 1 : 0)); 5409 1.1 mrg tree src = gimple_call_arg (t, (DECL_FUNCTION_CODE (decl) 5410 1.1 mrg == BUILT_IN_BCOPY ? 0 : 1)); 5411 1.1 mrg unsigned i; 5412 1.1 mrg struct constraint_expr *rhsp, *lhsp; 5413 1.1 mrg get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc); 5414 1.1 mrg lhs = get_function_part_constraint (fi, fi_clobbers); 5415 1.1 mrg FOR_EACH_VEC_ELT (lhsc, i, lhsp) 5416 1.1 mrg process_constraint (new_constraint (lhs, *lhsp)); 5417 1.1 mrg get_constraint_for_ptr_offset (src, NULL_TREE, &rhsc); 5418 1.1 mrg lhs = get_function_part_constraint (fi, fi_uses); 5419 1.1 mrg FOR_EACH_VEC_ELT (rhsc, i, rhsp) 5420 1.1 mrg process_constraint (new_constraint (lhs, *rhsp)); 5421 1.1 mrg return; 5422 1.1 mrg } 5423 1.1 mrg /* The following function clobbers memory pointed to by 5424 1.1 mrg its argument. */ 5425 1.1 mrg case BUILT_IN_MEMSET: 5426 1.1 mrg case BUILT_IN_MEMSET_CHK: 5427 1.1 mrg case BUILT_IN_POSIX_MEMALIGN: 5428 1.1 mrg { 5429 1.1 mrg tree dest = gimple_call_arg (t, 0); 5430 1.1 mrg unsigned i; 5431 1.1 mrg ce_s *lhsp; 5432 1.1 mrg get_constraint_for_ptr_offset (dest, NULL_TREE, &lhsc); 5433 1.1 mrg lhs = get_function_part_constraint (fi, fi_clobbers); 5434 1.1 mrg FOR_EACH_VEC_ELT (lhsc, i, lhsp) 5435 1.1 mrg process_constraint (new_constraint (lhs, *lhsp)); 5436 1.1 mrg return; 5437 1.1 mrg } 5438 1.1 mrg /* The following functions clobber their second and third 5439 1.1 mrg arguments. */ 5440 1.1 mrg case BUILT_IN_SINCOS: 5441 1.1 mrg case BUILT_IN_SINCOSF: 5442 1.1 mrg case BUILT_IN_SINCOSL: 5443 1.1 mrg { 5444 1.1 mrg process_ipa_clobber (fi, gimple_call_arg (t, 1)); 5445 1.1 mrg process_ipa_clobber (fi, gimple_call_arg (t, 2)); 5446 1.1 mrg return; 5447 1.1 mrg } 5448 1.1 mrg /* The following functions clobber their second argument. */ 5449 1.1 mrg case BUILT_IN_FREXP: 5450 1.1 mrg case BUILT_IN_FREXPF: 5451 1.1 mrg case BUILT_IN_FREXPL: 5452 1.1 mrg case BUILT_IN_LGAMMA_R: 5453 1.1 mrg case BUILT_IN_LGAMMAF_R: 5454 1.1 mrg case BUILT_IN_LGAMMAL_R: 5455 1.1 mrg case BUILT_IN_GAMMA_R: 5456 1.1 mrg case BUILT_IN_GAMMAF_R: 5457 1.1 mrg case BUILT_IN_GAMMAL_R: 5458 1.1 mrg case BUILT_IN_MODF: 5459 1.1 mrg case BUILT_IN_MODFF: 5460 1.1 mrg case BUILT_IN_MODFL: 5461 1.1 mrg { 5462 1.1 mrg process_ipa_clobber (fi, gimple_call_arg (t, 1)); 5463 1.1 mrg return; 5464 1.1 mrg } 5465 1.1 mrg /* The following functions clobber their third argument. */ 5466 1.1 mrg case BUILT_IN_REMQUO: 5467 1.1 mrg case BUILT_IN_REMQUOF: 5468 1.1 mrg case BUILT_IN_REMQUOL: 5469 1.1 mrg { 5470 1.1 mrg process_ipa_clobber (fi, gimple_call_arg (t, 2)); 5471 1.1 mrg return; 5472 1.1 mrg } 5473 1.1 mrg /* The following functions neither read nor clobber memory. */ 5474 1.1 mrg case BUILT_IN_ASSUME_ALIGNED: 5475 1.1 mrg case BUILT_IN_FREE: 5476 1.1 mrg return; 5477 1.1 mrg /* Trampolines are of no interest to us. */ 5478 1.1 mrg case BUILT_IN_INIT_TRAMPOLINE: 5479 1.1 mrg case BUILT_IN_ADJUST_TRAMPOLINE: 5480 1.1 mrg return; 5481 1.1 mrg case BUILT_IN_VA_START: 5482 1.1 mrg case BUILT_IN_VA_END: 5483 1.1 mrg return; 5484 1.1 mrg case BUILT_IN_GOMP_PARALLEL: 5485 1.1 mrg case BUILT_IN_GOACC_PARALLEL: 5486 1.1 mrg { 5487 1.1 mrg unsigned int fnpos, argpos; 5488 1.1 mrg unsigned int implicit_use_args[2]; 5489 1.1 mrg unsigned int num_implicit_use_args = 0; 5490 1.1 mrg switch (DECL_FUNCTION_CODE (decl)) 5491 1.1 mrg { 5492 1.1 mrg case BUILT_IN_GOMP_PARALLEL: 5493 1.1 mrg /* __builtin_GOMP_parallel (fn, data, num_threads, flags). */ 5494 1.1 mrg fnpos = 0; 5495 1.1 mrg argpos = 1; 5496 1.1 mrg break; 5497 1.1 mrg case BUILT_IN_GOACC_PARALLEL: 5498 1.1 mrg /* __builtin_GOACC_parallel (flags_m, fn, mapnum, hostaddrs, 5499 1.1 mrg sizes, kinds, ...). */ 5500 1.1 mrg fnpos = 1; 5501 1.1 mrg argpos = 3; 5502 1.1 mrg implicit_use_args[num_implicit_use_args++] = 4; 5503 1.1 mrg implicit_use_args[num_implicit_use_args++] = 5; 5504 1.1 mrg break; 5505 1.1 mrg default: 5506 1.1 mrg gcc_unreachable (); 5507 1.1 mrg } 5508 1.1 mrg 5509 1.1 mrg tree fnarg = gimple_call_arg (t, fnpos); 5510 1.1 mrg gcc_assert (TREE_CODE (fnarg) == ADDR_EXPR); 5511 1.1 mrg tree fndecl = TREE_OPERAND (fnarg, 0); 5512 1.1 mrg if (fndecl_maybe_in_other_partition (fndecl)) 5513 1.1 mrg /* Fallthru to general call handling. */ 5514 1.1 mrg break; 5515 1.1 mrg 5516 1.1 mrg varinfo_t cfi = get_vi_for_tree (fndecl); 5517 1.1 mrg 5518 1.1 mrg tree arg = gimple_call_arg (t, argpos); 5519 1.1 mrg 5520 1.1 mrg /* Parameter passed by value is used. */ 5521 1.1 mrg lhs = get_function_part_constraint (fi, fi_uses); 5522 1.1 mrg struct constraint_expr *rhsp; 5523 1.1 mrg get_constraint_for (arg, &rhsc); 5524 1.1 mrg FOR_EACH_VEC_ELT (rhsc, j, rhsp) 5525 1.1 mrg process_constraint (new_constraint (lhs, *rhsp)); 5526 1.1 mrg rhsc.truncate (0); 5527 1.1 mrg 5528 1.1 mrg /* Handle parameters used by the call, but not used in cfi, as 5529 1.1 mrg implicitly used by cfi. */ 5530 1.1 mrg lhs = get_function_part_constraint (cfi, fi_uses); 5531 1.1 mrg for (unsigned i = 0; i < num_implicit_use_args; ++i) 5532 1.1 mrg { 5533 1.1 mrg tree arg = gimple_call_arg (t, implicit_use_args[i]); 5534 1.1 mrg get_constraint_for (arg, &rhsc); 5535 1.1 mrg FOR_EACH_VEC_ELT (rhsc, j, rhsp) 5536 1.1 mrg process_constraint (new_constraint (lhs, *rhsp)); 5537 1.1 mrg rhsc.truncate (0); 5538 1.1 mrg } 5539 1.1 mrg 5540 1.1 mrg /* The caller clobbers what the callee does. */ 5541 1.1 mrg lhs = get_function_part_constraint (fi, fi_clobbers); 5542 1.1 mrg rhs = get_function_part_constraint (cfi, fi_clobbers); 5543 1.1 mrg process_constraint (new_constraint (lhs, rhs)); 5544 1.1 mrg 5545 1.1 mrg /* The caller uses what the callee does. */ 5546 1.1 mrg lhs = get_function_part_constraint (fi, fi_uses); 5547 1.1 mrg rhs = get_function_part_constraint (cfi, fi_uses); 5548 1.1 mrg process_constraint (new_constraint (lhs, rhs)); 5549 1.1 mrg 5550 1.1 mrg return; 5551 1.1 mrg } 5552 1.1 mrg /* printf-style functions may have hooks to set pointers to 5553 1.1 mrg point to somewhere into the generated string. Leave them 5554 1.1 mrg for a later exercise... */ 5555 1.1 mrg default: 5556 1.1 mrg /* Fallthru to general call handling. */; 5557 1.1 mrg } 5558 1.1 mrg 5559 1.1 mrg /* Parameters passed by value are used. */ 5560 1.1 mrg lhs = get_function_part_constraint (fi, fi_uses); 5561 1.1 mrg for (i = 0; i < gimple_call_num_args (t); i++) 5562 1.1 mrg { 5563 1.1 mrg struct constraint_expr *rhsp; 5564 1.1 mrg tree arg = gimple_call_arg (t, i); 5565 1.1 mrg 5566 1.1 mrg if (TREE_CODE (arg) == SSA_NAME 5567 1.1 mrg || is_gimple_min_invariant (arg)) 5568 1.1 mrg continue; 5569 1.1 mrg 5570 1.1 mrg get_constraint_for_address_of (arg, &rhsc); 5571 1.1 mrg FOR_EACH_VEC_ELT (rhsc, j, rhsp) 5572 1.1 mrg process_constraint (new_constraint (lhs, *rhsp)); 5573 1.1 mrg rhsc.truncate (0); 5574 1.1 mrg } 5575 1.1 mrg 5576 1.1 mrg /* Build constraints for propagating clobbers/uses along the 5577 1.1 mrg callgraph edges. */ 5578 1.1 mrg cfi = get_fi_for_callee (call_stmt); 5579 1.1 mrg if (cfi->id == anything_id) 5580 1.1 mrg { 5581 1.1 mrg if (gimple_vdef (t)) 5582 1.1 mrg make_constraint_from (first_vi_for_offset (fi, fi_clobbers), 5583 1.1 mrg anything_id); 5584 1.1 mrg make_constraint_from (first_vi_for_offset (fi, fi_uses), 5585 1.1 mrg anything_id); 5586 1.1 mrg return; 5587 1.1 mrg } 5588 1.1 mrg 5589 1.1 mrg /* For callees without function info (that's external functions), 5590 1.1 mrg ESCAPED is clobbered and used. */ 5591 1.1 mrg if (cfi->decl 5592 1.1 mrg && TREE_CODE (cfi->decl) == FUNCTION_DECL 5593 1.1 mrg && !cfi->is_fn_info) 5594 1.1 mrg { 5595 1.1 mrg varinfo_t vi; 5596 1.1 mrg 5597 1.1 mrg if (gimple_vdef (t)) 5598 1.1 mrg make_copy_constraint (first_vi_for_offset (fi, fi_clobbers), 5599 1.1 mrg escaped_id); 5600 1.1 mrg make_copy_constraint (first_vi_for_offset (fi, fi_uses), escaped_id); 5601 1.1 mrg 5602 1.1 mrg /* Also honor the call statement use/clobber info. */ 5603 1.1 mrg if ((vi = lookup_call_clobber_vi (call_stmt)) != NULL) 5604 1.1 mrg make_copy_constraint (first_vi_for_offset (fi, fi_clobbers), 5605 1.1 mrg vi->id); 5606 1.1 mrg if ((vi = lookup_call_use_vi (call_stmt)) != NULL) 5607 1.1 mrg make_copy_constraint (first_vi_for_offset (fi, fi_uses), 5608 1.1 mrg vi->id); 5609 1.1 mrg return; 5610 1.1 mrg } 5611 1.1 mrg 5612 1.1 mrg /* Otherwise the caller clobbers and uses what the callee does. 5613 1.1 mrg ??? This should use a new complex constraint that filters 5614 1.1 mrg local variables of the callee. */ 5615 1.1 mrg if (gimple_vdef (t)) 5616 1.1 mrg { 5617 1.1 mrg lhs = get_function_part_constraint (fi, fi_clobbers); 5618 1.1 mrg rhs = get_function_part_constraint (cfi, fi_clobbers); 5619 1.1 mrg process_constraint (new_constraint (lhs, rhs)); 5620 1.1 mrg } 5621 1.1 mrg lhs = get_function_part_constraint (fi, fi_uses); 5622 1.1 mrg rhs = get_function_part_constraint (cfi, fi_uses); 5623 1.1 mrg process_constraint (new_constraint (lhs, rhs)); 5624 1.1 mrg } 5625 1.1 mrg else if (gimple_code (t) == GIMPLE_ASM) 5626 1.1 mrg { 5627 1.1 mrg /* ??? Ick. We can do better. */ 5628 1.1 mrg if (gimple_vdef (t)) 5629 1.1 mrg make_constraint_from (first_vi_for_offset (fi, fi_clobbers), 5630 1.1 mrg anything_id); 5631 1.1 mrg make_constraint_from (first_vi_for_offset (fi, fi_uses), 5632 1.1 mrg anything_id); 5633 1.1 mrg } 5634 1.1 mrg } 5635 1.1 mrg 5636 1.1 mrg 5637 1.1 mrg /* Find the first varinfo in the same variable as START that overlaps with 5638 1.1 mrg OFFSET. Return NULL if we can't find one. */ 5639 1.1 mrg 5640 1.1 mrg static varinfo_t 5641 1.1 mrg first_vi_for_offset (varinfo_t start, unsigned HOST_WIDE_INT offset) 5642 1.1 mrg { 5643 1.1 mrg /* If the offset is outside of the variable, bail out. */ 5644 1.1 mrg if (offset >= start->fullsize) 5645 1.1 mrg return NULL; 5646 1.1 mrg 5647 1.1 mrg /* If we cannot reach offset from start, lookup the first field 5648 1.1 mrg and start from there. */ 5649 1.1 mrg if (start->offset > offset) 5650 1.1 mrg start = get_varinfo (start->head); 5651 1.1 mrg 5652 1.1 mrg while (start) 5653 1.1 mrg { 5654 1.1 mrg /* We may not find a variable in the field list with the actual 5655 1.1 mrg offset when we have glommed a structure to a variable. 5656 1.1 mrg In that case, however, offset should still be within the size 5657 1.1 mrg of the variable. */ 5658 1.1 mrg if (offset >= start->offset 5659 1.1 mrg && (offset - start->offset) < start->size) 5660 1.1 mrg return start; 5661 1.1 mrg 5662 1.1 mrg start = vi_next (start); 5663 1.1 mrg } 5664 1.1 mrg 5665 1.1 mrg return NULL; 5666 1.1 mrg } 5667 1.1 mrg 5668 1.1 mrg /* Find the first varinfo in the same variable as START that overlaps with 5669 1.1 mrg OFFSET. If there is no such varinfo the varinfo directly preceding 5670 1.1 mrg OFFSET is returned. */ 5671 1.1 mrg 5672 1.1 mrg static varinfo_t 5673 1.1 mrg first_or_preceding_vi_for_offset (varinfo_t start, 5674 1.1 mrg unsigned HOST_WIDE_INT offset) 5675 1.1 mrg { 5676 1.1 mrg /* If we cannot reach offset from start, lookup the first field 5677 1.1 mrg and start from there. */ 5678 1.1 mrg if (start->offset > offset) 5679 1.1 mrg start = get_varinfo (start->head); 5680 1.1 mrg 5681 1.1 mrg /* We may not find a variable in the field list with the actual 5682 1.1 mrg offset when we have glommed a structure to a variable. 5683 1.1 mrg In that case, however, offset should still be within the size 5684 1.1 mrg of the variable. 5685 1.1 mrg If we got beyond the offset we look for return the field 5686 1.1 mrg directly preceding offset which may be the last field. */ 5687 1.1 mrg while (start->next 5688 1.1 mrg && offset >= start->offset 5689 1.1 mrg && !((offset - start->offset) < start->size)) 5690 1.1 mrg start = vi_next (start); 5691 1.1 mrg 5692 1.1 mrg return start; 5693 1.1 mrg } 5694 1.1 mrg 5695 1.1 mrg 5696 1.1 mrg /* This structure is used during pushing fields onto the fieldstack 5697 1.1 mrg to track the offset of the field, since bitpos_of_field gives it 5698 1.1 mrg relative to its immediate containing type, and we want it relative 5699 1.1 mrg to the ultimate containing object. */ 5700 1.1 mrg 5701 1.1 mrg struct fieldoff 5702 1.1 mrg { 5703 1.1 mrg /* Offset from the base of the base containing object to this field. */ 5704 1.1 mrg HOST_WIDE_INT offset; 5705 1.1 mrg 5706 1.1 mrg /* Size, in bits, of the field. */ 5707 1.1 mrg unsigned HOST_WIDE_INT size; 5708 1.1 mrg 5709 1.1 mrg unsigned has_unknown_size : 1; 5710 1.1 mrg 5711 1.1 mrg unsigned must_have_pointers : 1; 5712 1.1 mrg 5713 1.1 mrg unsigned may_have_pointers : 1; 5714 1.1 mrg 5715 1.1 mrg unsigned only_restrict_pointers : 1; 5716 1.1 mrg 5717 1.1 mrg tree restrict_pointed_type; 5718 1.1 mrg }; 5719 1.1 mrg typedef struct fieldoff fieldoff_s; 5720 1.1 mrg 5721 1.1 mrg 5722 1.1 mrg /* qsort comparison function for two fieldoff's PA and PB */ 5723 1.1 mrg 5724 1.1 mrg static int 5725 1.1 mrg fieldoff_compare (const void *pa, const void *pb) 5726 1.1 mrg { 5727 1.1 mrg const fieldoff_s *foa = (const fieldoff_s *)pa; 5728 1.1 mrg const fieldoff_s *fob = (const fieldoff_s *)pb; 5729 1.1 mrg unsigned HOST_WIDE_INT foasize, fobsize; 5730 1.1 mrg 5731 1.1 mrg if (foa->offset < fob->offset) 5732 1.1 mrg return -1; 5733 1.1 mrg else if (foa->offset > fob->offset) 5734 1.1 mrg return 1; 5735 1.1 mrg 5736 1.1 mrg foasize = foa->size; 5737 1.1 mrg fobsize = fob->size; 5738 1.1 mrg if (foasize < fobsize) 5739 1.1 mrg return -1; 5740 1.1 mrg else if (foasize > fobsize) 5741 1.1 mrg return 1; 5742 1.1 mrg return 0; 5743 1.1 mrg } 5744 1.1 mrg 5745 1.1 mrg /* Sort a fieldstack according to the field offset and sizes. */ 5746 1.1 mrg static void 5747 1.1 mrg sort_fieldstack (vec<fieldoff_s> &fieldstack) 5748 1.1 mrg { 5749 1.1 mrg fieldstack.qsort (fieldoff_compare); 5750 1.1 mrg } 5751 1.1 mrg 5752 1.1 mrg /* Return true if T is a type that can have subvars. */ 5753 1.1 mrg 5754 1.1 mrg static inline bool 5755 1.1 mrg type_can_have_subvars (const_tree t) 5756 1.1 mrg { 5757 1.1 mrg /* Aggregates without overlapping fields can have subvars. */ 5758 1.1 mrg return TREE_CODE (t) == RECORD_TYPE; 5759 1.1 mrg } 5760 1.1 mrg 5761 1.1 mrg /* Return true if V is a tree that we can have subvars for. 5762 1.1 mrg Normally, this is any aggregate type. Also complex 5763 1.1 mrg types which are not gimple registers can have subvars. */ 5764 1.1 mrg 5765 1.1 mrg static inline bool 5766 1.1 mrg var_can_have_subvars (const_tree v) 5767 1.1 mrg { 5768 1.1 mrg /* Volatile variables should never have subvars. */ 5769 1.1 mrg if (TREE_THIS_VOLATILE (v)) 5770 1.1 mrg return false; 5771 1.1 mrg 5772 1.1 mrg /* Non decls or memory tags can never have subvars. */ 5773 1.1 mrg if (!DECL_P (v)) 5774 1.1 mrg return false; 5775 1.1 mrg 5776 1.1 mrg return type_can_have_subvars (TREE_TYPE (v)); 5777 1.1 mrg } 5778 1.1 mrg 5779 1.1 mrg /* Return true if T is a type that does contain pointers. */ 5780 1.1 mrg 5781 1.1 mrg static bool 5782 1.1 mrg type_must_have_pointers (tree type) 5783 1.1 mrg { 5784 1.1 mrg if (POINTER_TYPE_P (type)) 5785 1.1 mrg return true; 5786 1.1 mrg 5787 1.1 mrg if (TREE_CODE (type) == ARRAY_TYPE) 5788 1.1 mrg return type_must_have_pointers (TREE_TYPE (type)); 5789 1.1 mrg 5790 1.1 mrg /* A function or method can have pointers as arguments, so track 5791 1.1 mrg those separately. */ 5792 1.1 mrg if (TREE_CODE (type) == FUNCTION_TYPE 5793 1.1 mrg || TREE_CODE (type) == METHOD_TYPE) 5794 1.1 mrg return true; 5795 1.1 mrg 5796 1.1 mrg return false; 5797 1.1 mrg } 5798 1.1 mrg 5799 1.1 mrg static bool 5800 1.1 mrg field_must_have_pointers (tree t) 5801 1.1 mrg { 5802 1.1 mrg return type_must_have_pointers (TREE_TYPE (t)); 5803 1.1 mrg } 5804 1.1 mrg 5805 1.1 mrg /* Given a TYPE, and a vector of field offsets FIELDSTACK, push all 5806 1.1 mrg the fields of TYPE onto fieldstack, recording their offsets along 5807 1.1 mrg the way. 5808 1.1 mrg 5809 1.1 mrg OFFSET is used to keep track of the offset in this entire 5810 1.1 mrg structure, rather than just the immediately containing structure. 5811 1.1 mrg Returns false if the caller is supposed to handle the field we 5812 1.1 mrg recursed for. */ 5813 1.1 mrg 5814 1.1 mrg static bool 5815 1.1 mrg push_fields_onto_fieldstack (tree type, vec<fieldoff_s> *fieldstack, 5816 1.1 mrg HOST_WIDE_INT offset) 5817 1.1 mrg { 5818 1.1 mrg tree field; 5819 1.1 mrg bool empty_p = true; 5820 1.1 mrg 5821 1.1 mrg if (TREE_CODE (type) != RECORD_TYPE) 5822 1.1 mrg return false; 5823 1.1 mrg 5824 1.1 mrg /* If the vector of fields is growing too big, bail out early. 5825 1.1 mrg Callers check for vec::length <= param_max_fields_for_field_sensitive, make 5826 1.1 mrg sure this fails. */ 5827 1.1 mrg if (fieldstack->length () > (unsigned)param_max_fields_for_field_sensitive) 5828 1.1 mrg return false; 5829 1.1 mrg 5830 1.1 mrg for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) 5831 1.1 mrg if (TREE_CODE (field) == FIELD_DECL) 5832 1.1 mrg { 5833 1.1 mrg bool push = false; 5834 1.1 mrg HOST_WIDE_INT foff = bitpos_of_field (field); 5835 1.1 mrg tree field_type = TREE_TYPE (field); 5836 1.1 mrg 5837 1.1 mrg if (!var_can_have_subvars (field) 5838 1.1 mrg || TREE_CODE (field_type) == QUAL_UNION_TYPE 5839 1.1 mrg || TREE_CODE (field_type) == UNION_TYPE) 5840 1.1 mrg push = true; 5841 1.1 mrg else if (!push_fields_onto_fieldstack 5842 1.1 mrg (field_type, fieldstack, offset + foff) 5843 1.1 mrg && (DECL_SIZE (field) 5844 1.1 mrg && !integer_zerop (DECL_SIZE (field)))) 5845 1.1 mrg /* Empty structures may have actual size, like in C++. So 5846 1.1 mrg see if we didn't push any subfields and the size is 5847 1.1 mrg nonzero, push the field onto the stack. */ 5848 1.1 mrg push = true; 5849 1.1 mrg 5850 1.1 mrg if (push) 5851 1.1 mrg { 5852 1.1 mrg fieldoff_s *pair = NULL; 5853 1.1 mrg bool has_unknown_size = false; 5854 1.1 mrg bool must_have_pointers_p; 5855 1.1 mrg 5856 1.1 mrg if (!fieldstack->is_empty ()) 5857 1.1 mrg pair = &fieldstack->last (); 5858 1.1 mrg 5859 1.1 mrg /* If there isn't anything at offset zero, create sth. */ 5860 1.1 mrg if (!pair 5861 1.1 mrg && offset + foff != 0) 5862 1.1 mrg { 5863 1.1 mrg fieldoff_s e 5864 1.1 mrg = {0, offset + foff, false, false, true, false, NULL_TREE}; 5865 1.1 mrg pair = fieldstack->safe_push (e); 5866 1.1 mrg } 5867 1.1 mrg 5868 1.1 mrg if (!DECL_SIZE (field) 5869 1.1 mrg || !tree_fits_uhwi_p (DECL_SIZE (field))) 5870 1.1 mrg has_unknown_size = true; 5871 1.1 mrg 5872 1.1 mrg /* If adjacent fields do not contain pointers merge them. */ 5873 1.1 mrg must_have_pointers_p = field_must_have_pointers (field); 5874 1.1 mrg if (pair 5875 1.1 mrg && !has_unknown_size 5876 1.1 mrg && !must_have_pointers_p 5877 1.1 mrg && !pair->must_have_pointers 5878 1.1 mrg && !pair->has_unknown_size 5879 1.1 mrg && pair->offset + (HOST_WIDE_INT)pair->size == offset + foff) 5880 1.1 mrg { 5881 1.1 mrg pair->size += tree_to_uhwi (DECL_SIZE (field)); 5882 1.1 mrg } 5883 1.1 mrg else 5884 1.1 mrg { 5885 1.1 mrg fieldoff_s e; 5886 1.1 mrg e.offset = offset + foff; 5887 1.1 mrg e.has_unknown_size = has_unknown_size; 5888 1.1 mrg if (!has_unknown_size) 5889 1.1 mrg e.size = tree_to_uhwi (DECL_SIZE (field)); 5890 1.1 mrg else 5891 1.1 mrg e.size = -1; 5892 1.1 mrg e.must_have_pointers = must_have_pointers_p; 5893 1.1 mrg e.may_have_pointers = true; 5894 1.1 mrg e.only_restrict_pointers 5895 1.1 mrg = (!has_unknown_size 5896 1.1 mrg && POINTER_TYPE_P (field_type) 5897 1.1 mrg && TYPE_RESTRICT (field_type)); 5898 1.1 mrg if (e.only_restrict_pointers) 5899 1.1 mrg e.restrict_pointed_type = TREE_TYPE (field_type); 5900 1.1 mrg fieldstack->safe_push (e); 5901 1.1 mrg } 5902 1.1 mrg } 5903 1.1 mrg 5904 1.1 mrg empty_p = false; 5905 1.1 mrg } 5906 1.1 mrg 5907 1.1 mrg return !empty_p; 5908 1.1 mrg } 5909 1.1 mrg 5910 1.1 mrg /* Count the number of arguments DECL has, and set IS_VARARGS to true 5911 1.1 mrg if it is a varargs function. */ 5912 1.1 mrg 5913 1.1 mrg static unsigned int 5914 1.1 mrg count_num_arguments (tree decl, bool *is_varargs) 5915 1.1 mrg { 5916 1.1 mrg unsigned int num = 0; 5917 1.1 mrg tree t; 5918 1.1 mrg 5919 1.1 mrg /* Capture named arguments for K&R functions. They do not 5920 1.1 mrg have a prototype and thus no TYPE_ARG_TYPES. */ 5921 1.1 mrg for (t = DECL_ARGUMENTS (decl); t; t = DECL_CHAIN (t)) 5922 1.1 mrg ++num; 5923 1.1 mrg 5924 1.1 mrg /* Check if the function has variadic arguments. */ 5925 1.1 mrg for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t)) 5926 1.1 mrg if (TREE_VALUE (t) == void_type_node) 5927 1.1 mrg break; 5928 1.1 mrg if (!t) 5929 1.1 mrg *is_varargs = true; 5930 1.1 mrg 5931 1.1 mrg return num; 5932 1.1 mrg } 5933 1.1 mrg 5934 1.1 mrg /* Creation function node for DECL, using NAME, and return the index 5935 1.1 mrg of the variable we've created for the function. If NONLOCAL_p, create 5936 1.1 mrg initial constraints. */ 5937 1.1 mrg 5938 1.1 mrg static varinfo_t 5939 1.1 mrg create_function_info_for (tree decl, const char *name, bool add_id, 5940 1.1 mrg bool nonlocal_p) 5941 1.1 mrg { 5942 1.1 mrg struct function *fn = DECL_STRUCT_FUNCTION (decl); 5943 1.1 mrg varinfo_t vi, prev_vi; 5944 1.1 mrg tree arg; 5945 1.1 mrg unsigned int i; 5946 1.1 mrg bool is_varargs = false; 5947 1.1 mrg unsigned int num_args = count_num_arguments (decl, &is_varargs); 5948 1.1 mrg 5949 1.1 mrg /* Create the variable info. */ 5950 1.1 mrg 5951 1.1 mrg vi = new_var_info (decl, name, add_id); 5952 1.1 mrg vi->offset = 0; 5953 1.1 mrg vi->size = 1; 5954 1.1 mrg vi->fullsize = fi_parm_base + num_args; 5955 1.1 mrg vi->is_fn_info = 1; 5956 1.1 mrg vi->may_have_pointers = false; 5957 1.1 mrg if (is_varargs) 5958 1.1 mrg vi->fullsize = ~0; 5959 1.1 mrg insert_vi_for_tree (vi->decl, vi); 5960 1.1 mrg 5961 1.1 mrg prev_vi = vi; 5962 1.1 mrg 5963 1.1 mrg /* Create a variable for things the function clobbers and one for 5964 1.1 mrg things the function uses. */ 5965 1.1 mrg { 5966 1.1 mrg varinfo_t clobbervi, usevi; 5967 1.1 mrg const char *newname; 5968 1.1 mrg char *tempname; 5969 1.1 mrg 5970 1.1 mrg tempname = xasprintf ("%s.clobber", name); 5971 1.1 mrg newname = ggc_strdup (tempname); 5972 1.1 mrg free (tempname); 5973 1.1 mrg 5974 1.1 mrg clobbervi = new_var_info (NULL, newname, false); 5975 1.1 mrg clobbervi->offset = fi_clobbers; 5976 1.1 mrg clobbervi->size = 1; 5977 1.1 mrg clobbervi->fullsize = vi->fullsize; 5978 1.1 mrg clobbervi->is_full_var = true; 5979 1.1 mrg clobbervi->is_global_var = false; 5980 1.1 mrg clobbervi->is_reg_var = true; 5981 1.1 mrg 5982 1.1 mrg gcc_assert (prev_vi->offset < clobbervi->offset); 5983 1.1 mrg prev_vi->next = clobbervi->id; 5984 1.1 mrg prev_vi = clobbervi; 5985 1.1 mrg 5986 1.1 mrg tempname = xasprintf ("%s.use", name); 5987 1.1 mrg newname = ggc_strdup (tempname); 5988 1.1 mrg free (tempname); 5989 1.1 mrg 5990 1.1 mrg usevi = new_var_info (NULL, newname, false); 5991 1.1 mrg usevi->offset = fi_uses; 5992 1.1 mrg usevi->size = 1; 5993 1.1 mrg usevi->fullsize = vi->fullsize; 5994 1.1 mrg usevi->is_full_var = true; 5995 1.1 mrg usevi->is_global_var = false; 5996 1.1 mrg usevi->is_reg_var = true; 5997 1.1 mrg 5998 1.1 mrg gcc_assert (prev_vi->offset < usevi->offset); 5999 1.1 mrg prev_vi->next = usevi->id; 6000 1.1 mrg prev_vi = usevi; 6001 1.1 mrg } 6002 1.1 mrg 6003 1.1 mrg /* And one for the static chain. */ 6004 1.1 mrg if (fn->static_chain_decl != NULL_TREE) 6005 1.1 mrg { 6006 1.1 mrg varinfo_t chainvi; 6007 1.1 mrg const char *newname; 6008 1.1 mrg char *tempname; 6009 1.1 mrg 6010 1.1 mrg tempname = xasprintf ("%s.chain", name); 6011 1.1 mrg newname = ggc_strdup (tempname); 6012 1.1 mrg free (tempname); 6013 1.1 mrg 6014 1.1 mrg chainvi = new_var_info (fn->static_chain_decl, newname, false); 6015 1.1 mrg chainvi->offset = fi_static_chain; 6016 1.1 mrg chainvi->size = 1; 6017 1.1 mrg chainvi->fullsize = vi->fullsize; 6018 1.1 mrg chainvi->is_full_var = true; 6019 1.1 mrg chainvi->is_global_var = false; 6020 1.1 mrg 6021 1.1 mrg insert_vi_for_tree (fn->static_chain_decl, chainvi); 6022 1.1 mrg 6023 1.1 mrg if (nonlocal_p 6024 1.1 mrg && chainvi->may_have_pointers) 6025 1.1 mrg make_constraint_from (chainvi, nonlocal_id); 6026 1.1 mrg 6027 1.1 mrg gcc_assert (prev_vi->offset < chainvi->offset); 6028 1.1 mrg prev_vi->next = chainvi->id; 6029 1.1 mrg prev_vi = chainvi; 6030 1.1 mrg } 6031 1.1 mrg 6032 1.1 mrg /* Create a variable for the return var. */ 6033 1.1 mrg if (DECL_RESULT (decl) != NULL 6034 1.1 mrg || !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl)))) 6035 1.1 mrg { 6036 1.1 mrg varinfo_t resultvi; 6037 1.1 mrg const char *newname; 6038 1.1 mrg char *tempname; 6039 1.1 mrg tree resultdecl = decl; 6040 1.1 mrg 6041 1.1 mrg if (DECL_RESULT (decl)) 6042 1.1 mrg resultdecl = DECL_RESULT (decl); 6043 1.1 mrg 6044 1.1 mrg tempname = xasprintf ("%s.result", name); 6045 1.1 mrg newname = ggc_strdup (tempname); 6046 1.1 mrg free (tempname); 6047 1.1 mrg 6048 1.1 mrg resultvi = new_var_info (resultdecl, newname, false); 6049 1.1 mrg resultvi->offset = fi_result; 6050 1.1 mrg resultvi->size = 1; 6051 1.1 mrg resultvi->fullsize = vi->fullsize; 6052 1.1 mrg resultvi->is_full_var = true; 6053 1.1 mrg if (DECL_RESULT (decl)) 6054 1.1 mrg resultvi->may_have_pointers = true; 6055 1.1 mrg 6056 1.1 mrg if (DECL_RESULT (decl)) 6057 1.1 mrg insert_vi_for_tree (DECL_RESULT (decl), resultvi); 6058 1.1 mrg 6059 1.1 mrg if (nonlocal_p 6060 1.1 mrg && DECL_RESULT (decl) 6061 1.1 mrg && DECL_BY_REFERENCE (DECL_RESULT (decl))) 6062 1.1 mrg make_constraint_from (resultvi, nonlocal_id); 6063 1.1 mrg 6064 1.1 mrg gcc_assert (prev_vi->offset < resultvi->offset); 6065 1.1 mrg prev_vi->next = resultvi->id; 6066 1.1 mrg prev_vi = resultvi; 6067 1.1 mrg } 6068 1.1 mrg 6069 1.1 mrg /* We also need to make function return values escape. Nothing 6070 1.1 mrg escapes by returning from main though. */ 6071 1.1 mrg if (nonlocal_p 6072 1.1 mrg && !MAIN_NAME_P (DECL_NAME (decl))) 6073 1.1 mrg { 6074 1.1 mrg varinfo_t fi, rvi; 6075 1.1 mrg fi = lookup_vi_for_tree (decl); 6076 1.1 mrg rvi = first_vi_for_offset (fi, fi_result); 6077 1.1 mrg if (rvi && rvi->offset == fi_result) 6078 1.1 mrg make_copy_constraint (get_varinfo (escaped_id), rvi->id); 6079 1.1 mrg } 6080 1.1 mrg 6081 1.1 mrg /* Set up variables for each argument. */ 6082 1.1 mrg arg = DECL_ARGUMENTS (decl); 6083 1.1 mrg for (i = 0; i < num_args; i++) 6084 1.1 mrg { 6085 1.1 mrg varinfo_t argvi; 6086 1.1 mrg const char *newname; 6087 1.1 mrg char *tempname; 6088 1.1 mrg tree argdecl = decl; 6089 1.1 mrg 6090 1.1 mrg if (arg) 6091 1.1 mrg argdecl = arg; 6092 1.1 mrg 6093 1.1 mrg tempname = xasprintf ("%s.arg%d", name, i); 6094 1.1 mrg newname = ggc_strdup (tempname); 6095 1.1 mrg free (tempname); 6096 1.1 mrg 6097 1.1 mrg argvi = new_var_info (argdecl, newname, false); 6098 1.1 mrg argvi->offset = fi_parm_base + i; 6099 1.1 mrg argvi->size = 1; 6100 1.1 mrg argvi->is_full_var = true; 6101 1.1 mrg argvi->fullsize = vi->fullsize; 6102 1.1 mrg if (arg) 6103 1.1 mrg argvi->may_have_pointers = true; 6104 1.1 mrg 6105 1.1 mrg if (arg) 6106 1.1 mrg insert_vi_for_tree (arg, argvi); 6107 1.1 mrg 6108 1.1 mrg if (nonlocal_p 6109 1.1 mrg && argvi->may_have_pointers) 6110 1.1 mrg make_constraint_from (argvi, nonlocal_id); 6111 1.1 mrg 6112 1.1 mrg gcc_assert (prev_vi->offset < argvi->offset); 6113 1.1 mrg prev_vi->next = argvi->id; 6114 1.1 mrg prev_vi = argvi; 6115 1.1 mrg if (arg) 6116 1.1 mrg arg = DECL_CHAIN (arg); 6117 1.1 mrg } 6118 1.1 mrg 6119 1.1 mrg /* Add one representative for all further args. */ 6120 1.1 mrg if (is_varargs) 6121 1.1 mrg { 6122 1.1 mrg varinfo_t argvi; 6123 1.1 mrg const char *newname; 6124 1.1 mrg char *tempname; 6125 1.1 mrg tree decl; 6126 1.1 mrg 6127 1.1 mrg tempname = xasprintf ("%s.varargs", name); 6128 1.1 mrg newname = ggc_strdup (tempname); 6129 1.1 mrg free (tempname); 6130 1.1 mrg 6131 1.1 mrg /* We need sth that can be pointed to for va_start. */ 6132 1.1 mrg decl = build_fake_var_decl (ptr_type_node); 6133 1.1 mrg 6134 1.1 mrg argvi = new_var_info (decl, newname, false); 6135 1.1 mrg argvi->offset = fi_parm_base + num_args; 6136 1.1 mrg argvi->size = ~0; 6137 1.1 mrg argvi->is_full_var = true; 6138 1.1 mrg argvi->is_heap_var = true; 6139 1.1 mrg argvi->fullsize = vi->fullsize; 6140 1.1 mrg 6141 1.1 mrg if (nonlocal_p 6142 1.1 mrg && argvi->may_have_pointers) 6143 1.1 mrg make_constraint_from (argvi, nonlocal_id); 6144 1.1 mrg 6145 1.1 mrg gcc_assert (prev_vi->offset < argvi->offset); 6146 1.1 mrg prev_vi->next = argvi->id; 6147 1.1 mrg } 6148 1.1 mrg 6149 1.1 mrg return vi; 6150 1.1 mrg } 6151 1.1 mrg 6152 1.1 mrg 6153 1.1 mrg /* Return true if FIELDSTACK contains fields that overlap. 6154 1.1 mrg FIELDSTACK is assumed to be sorted by offset. */ 6155 1.1 mrg 6156 1.1 mrg static bool 6157 1.1 mrg check_for_overlaps (const vec<fieldoff_s> &fieldstack) 6158 1.1 mrg { 6159 1.1 mrg fieldoff_s *fo = NULL; 6160 1.1 mrg unsigned int i; 6161 1.1 mrg HOST_WIDE_INT lastoffset = -1; 6162 1.1 mrg 6163 1.1 mrg FOR_EACH_VEC_ELT (fieldstack, i, fo) 6164 1.1 mrg { 6165 1.1 mrg if (fo->offset == lastoffset) 6166 1.1 mrg return true; 6167 1.1 mrg lastoffset = fo->offset; 6168 1.1 mrg } 6169 1.1 mrg return false; 6170 1.1 mrg } 6171 1.1 mrg 6172 1.1 mrg /* Create a varinfo structure for NAME and DECL, and add it to VARMAP. 6173 1.1 mrg This will also create any varinfo structures necessary for fields 6174 1.1 mrg of DECL. DECL is a function parameter if HANDLE_PARAM is set. 6175 1.1 mrg HANDLED_STRUCT_TYPE is used to register struct types reached by following 6176 1.1 mrg restrict pointers. This is needed to prevent infinite recursion. 6177 1.1 mrg If ADD_RESTRICT, pretend that the pointer NAME is restrict even if DECL 6178 1.1 mrg does not advertise it. */ 6179 1.1 mrg 6180 1.1 mrg static varinfo_t 6181 1.1 mrg create_variable_info_for_1 (tree decl, const char *name, bool add_id, 6182 1.1 mrg bool handle_param, bitmap handled_struct_type, 6183 1.1 mrg bool add_restrict = false) 6184 1.1 mrg { 6185 1.1 mrg varinfo_t vi, newvi; 6186 1.1 mrg tree decl_type = TREE_TYPE (decl); 6187 1.1 mrg tree declsize = DECL_P (decl) ? DECL_SIZE (decl) : TYPE_SIZE (decl_type); 6188 1.1 mrg auto_vec<fieldoff_s> fieldstack; 6189 1.1 mrg fieldoff_s *fo; 6190 1.1 mrg unsigned int i; 6191 1.1 mrg 6192 1.1 mrg if (!declsize 6193 1.1 mrg || !tree_fits_uhwi_p (declsize)) 6194 1.1 mrg { 6195 1.1 mrg vi = new_var_info (decl, name, add_id); 6196 1.1 mrg vi->offset = 0; 6197 1.1 mrg vi->size = ~0; 6198 1.1 mrg vi->fullsize = ~0; 6199 1.1 mrg vi->is_unknown_size_var = true; 6200 1.1 mrg vi->is_full_var = true; 6201 1.1 mrg vi->may_have_pointers = true; 6202 1.1 mrg return vi; 6203 1.1 mrg } 6204 1.1 mrg 6205 1.1 mrg /* Collect field information. */ 6206 1.1 mrg if (use_field_sensitive 6207 1.1 mrg && var_can_have_subvars (decl) 6208 1.1 mrg /* ??? Force us to not use subfields for globals in IPA mode. 6209 1.1 mrg Else we'd have to parse arbitrary initializers. */ 6210 1.1 mrg && !(in_ipa_mode 6211 1.1 mrg && is_global_var (decl))) 6212 1.1 mrg { 6213 1.1 mrg fieldoff_s *fo = NULL; 6214 1.1 mrg bool notokay = false; 6215 1.1 mrg unsigned int i; 6216 1.1 mrg 6217 1.1 mrg push_fields_onto_fieldstack (decl_type, &fieldstack, 0); 6218 1.1 mrg 6219 1.1 mrg for (i = 0; !notokay && fieldstack.iterate (i, &fo); i++) 6220 1.1 mrg if (fo->has_unknown_size 6221 1.1 mrg || fo->offset < 0) 6222 1.1 mrg { 6223 1.1 mrg notokay = true; 6224 1.1 mrg break; 6225 1.1 mrg } 6226 1.1 mrg 6227 1.1 mrg /* We can't sort them if we have a field with a variable sized type, 6228 1.1 mrg which will make notokay = true. In that case, we are going to return 6229 1.1 mrg without creating varinfos for the fields anyway, so sorting them is a 6230 1.1 mrg waste to boot. */ 6231 1.1 mrg if (!notokay) 6232 1.1 mrg { 6233 1.1 mrg sort_fieldstack (fieldstack); 6234 1.1 mrg /* Due to some C++ FE issues, like PR 22488, we might end up 6235 1.1 mrg what appear to be overlapping fields even though they, 6236 1.1 mrg in reality, do not overlap. Until the C++ FE is fixed, 6237 1.1 mrg we will simply disable field-sensitivity for these cases. */ 6238 1.1 mrg notokay = check_for_overlaps (fieldstack); 6239 1.1 mrg } 6240 1.1 mrg 6241 1.1 mrg if (notokay) 6242 1.1 mrg fieldstack.release (); 6243 1.1 mrg } 6244 1.1 mrg 6245 1.1 mrg /* If we didn't end up collecting sub-variables create a full 6246 1.1 mrg variable for the decl. */ 6247 1.1 mrg if (fieldstack.length () == 0 6248 1.1 mrg || fieldstack.length () > (unsigned)param_max_fields_for_field_sensitive) 6249 1.1 mrg { 6250 1.1 mrg vi = new_var_info (decl, name, add_id); 6251 1.1 mrg vi->offset = 0; 6252 1.1 mrg vi->may_have_pointers = true; 6253 1.1 mrg vi->fullsize = tree_to_uhwi (declsize); 6254 1.1 mrg vi->size = vi->fullsize; 6255 1.1 mrg vi->is_full_var = true; 6256 1.1 mrg if (POINTER_TYPE_P (decl_type) 6257 1.1 mrg && (TYPE_RESTRICT (decl_type) || add_restrict)) 6258 1.1 mrg vi->only_restrict_pointers = 1; 6259 1.1 mrg if (vi->only_restrict_pointers 6260 1.1 mrg && !type_contains_placeholder_p (TREE_TYPE (decl_type)) 6261 1.1 mrg && handle_param 6262 1.1 mrg && !bitmap_bit_p (handled_struct_type, 6263 1.1 mrg TYPE_UID (TREE_TYPE (decl_type)))) 6264 1.1 mrg { 6265 1.1 mrg varinfo_t rvi; 6266 1.1 mrg tree heapvar = build_fake_var_decl (TREE_TYPE (decl_type)); 6267 1.1 mrg DECL_EXTERNAL (heapvar) = 1; 6268 1.1 mrg if (var_can_have_subvars (heapvar)) 6269 1.1 mrg bitmap_set_bit (handled_struct_type, 6270 1.1 mrg TYPE_UID (TREE_TYPE (decl_type))); 6271 1.1 mrg rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true, 6272 1.1 mrg true, handled_struct_type); 6273 1.1 mrg if (var_can_have_subvars (heapvar)) 6274 1.1 mrg bitmap_clear_bit (handled_struct_type, 6275 1.1 mrg TYPE_UID (TREE_TYPE (decl_type))); 6276 1.1 mrg rvi->is_restrict_var = 1; 6277 1.1 mrg insert_vi_for_tree (heapvar, rvi); 6278 1.1 mrg make_constraint_from (vi, rvi->id); 6279 1.1 mrg make_param_constraints (rvi); 6280 1.1 mrg } 6281 1.1 mrg fieldstack.release (); 6282 1.1 mrg return vi; 6283 1.1 mrg } 6284 1.1 mrg 6285 1.1 mrg vi = new_var_info (decl, name, add_id); 6286 1.1 mrg vi->fullsize = tree_to_uhwi (declsize); 6287 1.1 mrg if (fieldstack.length () == 1) 6288 1.1 mrg vi->is_full_var = true; 6289 1.1 mrg for (i = 0, newvi = vi; 6290 1.1 mrg fieldstack.iterate (i, &fo); 6291 1.1 mrg ++i, newvi = vi_next (newvi)) 6292 1.1 mrg { 6293 1.1 mrg const char *newname = NULL; 6294 1.1 mrg char *tempname; 6295 1.1 mrg 6296 1.1 mrg if (dump_file) 6297 1.1 mrg { 6298 1.1 mrg if (fieldstack.length () != 1) 6299 1.1 mrg { 6300 1.1 mrg tempname 6301 1.1 mrg = xasprintf ("%s." HOST_WIDE_INT_PRINT_DEC 6302 1.1 mrg "+" HOST_WIDE_INT_PRINT_DEC, name, 6303 1.1 mrg fo->offset, fo->size); 6304 1.1 mrg newname = ggc_strdup (tempname); 6305 1.1 mrg free (tempname); 6306 1.1 mrg } 6307 1.1 mrg } 6308 1.1 mrg else 6309 1.1 mrg newname = "NULL"; 6310 1.1 mrg 6311 1.1 mrg if (newname) 6312 1.1 mrg newvi->name = newname; 6313 1.1 mrg newvi->offset = fo->offset; 6314 1.1 mrg newvi->size = fo->size; 6315 1.1 mrg newvi->fullsize = vi->fullsize; 6316 1.1 mrg newvi->may_have_pointers = fo->may_have_pointers; 6317 1.1 mrg newvi->only_restrict_pointers = fo->only_restrict_pointers; 6318 1.1 mrg if (handle_param 6319 1.1 mrg && newvi->only_restrict_pointers 6320 1.1 mrg && !type_contains_placeholder_p (fo->restrict_pointed_type) 6321 1.1 mrg && !bitmap_bit_p (handled_struct_type, 6322 1.1 mrg TYPE_UID (fo->restrict_pointed_type))) 6323 1.1 mrg { 6324 1.1 mrg varinfo_t rvi; 6325 1.1 mrg tree heapvar = build_fake_var_decl (fo->restrict_pointed_type); 6326 1.1 mrg DECL_EXTERNAL (heapvar) = 1; 6327 1.1 mrg if (var_can_have_subvars (heapvar)) 6328 1.1 mrg bitmap_set_bit (handled_struct_type, 6329 1.1 mrg TYPE_UID (fo->restrict_pointed_type)); 6330 1.1 mrg rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true, 6331 1.1 mrg true, handled_struct_type); 6332 1.1 mrg if (var_can_have_subvars (heapvar)) 6333 1.1 mrg bitmap_clear_bit (handled_struct_type, 6334 1.1 mrg TYPE_UID (fo->restrict_pointed_type)); 6335 1.1 mrg rvi->is_restrict_var = 1; 6336 1.1 mrg insert_vi_for_tree (heapvar, rvi); 6337 1.1 mrg make_constraint_from (newvi, rvi->id); 6338 1.1 mrg make_param_constraints (rvi); 6339 1.1 mrg } 6340 1.1 mrg if (i + 1 < fieldstack.length ()) 6341 1.1 mrg { 6342 1.1 mrg varinfo_t tem = new_var_info (decl, name, false); 6343 1.1 mrg newvi->next = tem->id; 6344 1.1 mrg tem->head = vi->id; 6345 1.1 mrg } 6346 1.1 mrg } 6347 1.1 mrg 6348 1.1 mrg return vi; 6349 1.1 mrg } 6350 1.1 mrg 6351 1.1 mrg static unsigned int 6352 1.1 mrg create_variable_info_for (tree decl, const char *name, bool add_id) 6353 1.1 mrg { 6354 1.1 mrg /* First see if we are dealing with an ifunc resolver call and 6355 1.1 mrg assiociate that with a call to the resolver function result. */ 6356 1.1 mrg cgraph_node *node; 6357 1.1 mrg if (in_ipa_mode 6358 1.1 mrg && TREE_CODE (decl) == FUNCTION_DECL 6359 1.1 mrg && (node = cgraph_node::get (decl)) 6360 1.1 mrg && node->ifunc_resolver) 6361 1.1 mrg { 6362 1.1 mrg varinfo_t fi = get_vi_for_tree (node->get_alias_target ()->decl); 6363 1.1 mrg constraint_expr rhs 6364 1.1 mrg = get_function_part_constraint (fi, fi_result); 6365 1.1 mrg fi = new_var_info (NULL_TREE, "ifuncres", true); 6366 1.1 mrg fi->is_reg_var = true; 6367 1.1 mrg constraint_expr lhs; 6368 1.1 mrg lhs.type = SCALAR; 6369 1.1 mrg lhs.var = fi->id; 6370 1.1 mrg lhs.offset = 0; 6371 1.1 mrg process_constraint (new_constraint (lhs, rhs)); 6372 1.1 mrg insert_vi_for_tree (decl, fi); 6373 1.1 mrg return fi->id; 6374 1.1 mrg } 6375 1.1 mrg 6376 1.1 mrg varinfo_t vi = create_variable_info_for_1 (decl, name, add_id, false, NULL); 6377 1.1 mrg unsigned int id = vi->id; 6378 1.1 mrg 6379 1.1 mrg insert_vi_for_tree (decl, vi); 6380 1.1 mrg 6381 1.1 mrg if (!VAR_P (decl)) 6382 1.1 mrg return id; 6383 1.1 mrg 6384 1.1 mrg /* Create initial constraints for globals. */ 6385 1.1 mrg for (; vi; vi = vi_next (vi)) 6386 1.1 mrg { 6387 1.1 mrg if (!vi->may_have_pointers 6388 1.1 mrg || !vi->is_global_var) 6389 1.1 mrg continue; 6390 1.1 mrg 6391 1.1 mrg /* Mark global restrict qualified pointers. */ 6392 1.1 mrg if ((POINTER_TYPE_P (TREE_TYPE (decl)) 6393 1.1 mrg && TYPE_RESTRICT (TREE_TYPE (decl))) 6394 1.1 mrg || vi->only_restrict_pointers) 6395 1.1 mrg { 6396 1.1 mrg varinfo_t rvi 6397 1.1 mrg = make_constraint_from_global_restrict (vi, "GLOBAL_RESTRICT", 6398 1.1 mrg true); 6399 1.1 mrg /* ??? For now exclude reads from globals as restrict sources 6400 1.1 mrg if those are not (indirectly) from incoming parameters. */ 6401 1.1 mrg rvi->is_restrict_var = false; 6402 1.1 mrg continue; 6403 1.1 mrg } 6404 1.1 mrg 6405 1.1 mrg /* In non-IPA mode the initializer from nonlocal is all we need. */ 6406 1.1 mrg if (!in_ipa_mode 6407 1.1 mrg || DECL_HARD_REGISTER (decl)) 6408 1.1 mrg make_copy_constraint (vi, nonlocal_id); 6409 1.1 mrg 6410 1.1 mrg /* In IPA mode parse the initializer and generate proper constraints 6411 1.1 mrg for it. */ 6412 1.1 mrg else 6413 1.1 mrg { 6414 1.1 mrg varpool_node *vnode = varpool_node::get (decl); 6415 1.1 mrg 6416 1.1 mrg /* For escaped variables initialize them from nonlocal. */ 6417 1.1 mrg if (!vnode->all_refs_explicit_p ()) 6418 1.1 mrg make_copy_constraint (vi, nonlocal_id); 6419 1.1 mrg 6420 1.1 mrg /* If this is a global variable with an initializer and we are in 6421 1.1 mrg IPA mode generate constraints for it. */ 6422 1.1 mrg ipa_ref *ref; 6423 1.1 mrg for (unsigned idx = 0; vnode->iterate_reference (idx, ref); ++idx) 6424 1.1 mrg { 6425 1.1 mrg auto_vec<ce_s> rhsc; 6426 1.1 mrg struct constraint_expr lhs, *rhsp; 6427 1.1 mrg unsigned i; 6428 1.1 mrg get_constraint_for_address_of (ref->referred->decl, &rhsc); 6429 1.1 mrg lhs.var = vi->id; 6430 1.1 mrg lhs.offset = 0; 6431 1.1 mrg lhs.type = SCALAR; 6432 1.1 mrg FOR_EACH_VEC_ELT (rhsc, i, rhsp) 6433 1.1 mrg process_constraint (new_constraint (lhs, *rhsp)); 6434 1.1 mrg /* If this is a variable that escapes from the unit 6435 1.1 mrg the initializer escapes as well. */ 6436 1.1 mrg if (!vnode->all_refs_explicit_p ()) 6437 1.1 mrg { 6438 1.1 mrg lhs.var = escaped_id; 6439 1.1 mrg lhs.offset = 0; 6440 1.1 mrg lhs.type = SCALAR; 6441 1.1 mrg FOR_EACH_VEC_ELT (rhsc, i, rhsp) 6442 1.1 mrg process_constraint (new_constraint (lhs, *rhsp)); 6443 1.1 mrg } 6444 1.1 mrg } 6445 1.1 mrg } 6446 1.1 mrg } 6447 1.1 mrg 6448 1.1 mrg return id; 6449 1.1 mrg } 6450 1.1 mrg 6451 1.1 mrg /* Print out the points-to solution for VAR to FILE. */ 6452 1.1 mrg 6453 1.1 mrg static void 6454 1.1 mrg dump_solution_for_var (FILE *file, unsigned int var) 6455 1.1 mrg { 6456 1.1 mrg varinfo_t vi = get_varinfo (var); 6457 1.1 mrg unsigned int i; 6458 1.1 mrg bitmap_iterator bi; 6459 1.1 mrg 6460 1.1 mrg /* Dump the solution for unified vars anyway, this avoids difficulties 6461 1.1 mrg in scanning dumps in the testsuite. */ 6462 1.1 mrg fprintf (file, "%s = { ", vi->name); 6463 1.1 mrg vi = get_varinfo (find (var)); 6464 1.1 mrg EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi) 6465 1.1 mrg fprintf (file, "%s ", get_varinfo (i)->name); 6466 1.1 mrg fprintf (file, "}"); 6467 1.1 mrg 6468 1.1 mrg /* But note when the variable was unified. */ 6469 1.1 mrg if (vi->id != var) 6470 1.1 mrg fprintf (file, " same as %s", vi->name); 6471 1.1 mrg 6472 1.1 mrg fprintf (file, "\n"); 6473 1.1 mrg } 6474 1.1 mrg 6475 1.1 mrg /* Print the points-to solution for VAR to stderr. */ 6476 1.1 mrg 6477 1.1 mrg DEBUG_FUNCTION void 6478 1.1 mrg debug_solution_for_var (unsigned int var) 6479 1.1 mrg { 6480 1.1 mrg dump_solution_for_var (stderr, var); 6481 1.1 mrg } 6482 1.1 mrg 6483 1.1 mrg /* Register the constraints for function parameter related VI. */ 6484 1.1 mrg 6485 1.1 mrg static void 6486 1.1 mrg make_param_constraints (varinfo_t vi) 6487 1.1 mrg { 6488 1.1 mrg for (; vi; vi = vi_next (vi)) 6489 1.1 mrg { 6490 1.1 mrg if (vi->only_restrict_pointers) 6491 1.1 mrg ; 6492 1.1 mrg else if (vi->may_have_pointers) 6493 1.1 mrg make_constraint_from (vi, nonlocal_id); 6494 1.1 mrg 6495 1.1 mrg if (vi->is_full_var) 6496 1.1 mrg break; 6497 1.1 mrg } 6498 1.1 mrg } 6499 1.1 mrg 6500 1.1 mrg /* Create varinfo structures for all of the variables in the 6501 1.1 mrg function for intraprocedural mode. */ 6502 1.1 mrg 6503 1.1 mrg static void 6504 1.1 mrg intra_create_variable_infos (struct function *fn) 6505 1.1 mrg { 6506 1.1 mrg tree t; 6507 1.1 mrg bitmap handled_struct_type = NULL; 6508 1.1 mrg bool this_parm_in_ctor = DECL_CXX_CONSTRUCTOR_P (fn->decl); 6509 1.1 mrg 6510 1.1 mrg /* For each incoming pointer argument arg, create the constraint ARG 6511 1.1 mrg = NONLOCAL or a dummy variable if it is a restrict qualified 6512 1.1 mrg passed-by-reference argument. */ 6513 1.1 mrg for (t = DECL_ARGUMENTS (fn->decl); t; t = DECL_CHAIN (t)) 6514 1.1 mrg { 6515 1.1 mrg if (handled_struct_type == NULL) 6516 1.1 mrg handled_struct_type = BITMAP_ALLOC (NULL); 6517 1.1 mrg 6518 1.1 mrg varinfo_t p 6519 1.1 mrg = create_variable_info_for_1 (t, alias_get_name (t), false, true, 6520 1.1 mrg handled_struct_type, this_parm_in_ctor); 6521 1.1 mrg insert_vi_for_tree (t, p); 6522 1.1 mrg 6523 1.1 mrg make_param_constraints (p); 6524 1.1 mrg 6525 1.1 mrg this_parm_in_ctor = false; 6526 1.1 mrg } 6527 1.1 mrg 6528 1.1 mrg if (handled_struct_type != NULL) 6529 1.1 mrg BITMAP_FREE (handled_struct_type); 6530 1.1 mrg 6531 1.1 mrg /* Add a constraint for a result decl that is passed by reference. */ 6532 1.1 mrg if (DECL_RESULT (fn->decl) 6533 1.1 mrg && DECL_BY_REFERENCE (DECL_RESULT (fn->decl))) 6534 1.1 mrg { 6535 1.1 mrg varinfo_t p, result_vi = get_vi_for_tree (DECL_RESULT (fn->decl)); 6536 1.1 mrg 6537 1.1 mrg for (p = result_vi; p; p = vi_next (p)) 6538 1.1 mrg make_constraint_from (p, nonlocal_id); 6539 1.1 mrg } 6540 1.1 mrg 6541 1.1 mrg /* Add a constraint for the incoming static chain parameter. */ 6542 1.1 mrg if (fn->static_chain_decl != NULL_TREE) 6543 1.1 mrg { 6544 1.1 mrg varinfo_t p, chain_vi = get_vi_for_tree (fn->static_chain_decl); 6545 1.1 mrg 6546 1.1 mrg for (p = chain_vi; p; p = vi_next (p)) 6547 1.1 mrg make_constraint_from (p, nonlocal_id); 6548 1.1 mrg } 6549 1.1 mrg } 6550 1.1 mrg 6551 1.1 mrg /* Structure used to put solution bitmaps in a hashtable so they can 6552 1.1 mrg be shared among variables with the same points-to set. */ 6553 1.1 mrg 6554 1.1 mrg typedef struct shared_bitmap_info 6555 1.1 mrg { 6556 1.1 mrg bitmap pt_vars; 6557 1.1 mrg hashval_t hashcode; 6558 1.1 mrg } *shared_bitmap_info_t; 6559 1.1 mrg typedef const struct shared_bitmap_info *const_shared_bitmap_info_t; 6560 1.1 mrg 6561 1.1 mrg /* Shared_bitmap hashtable helpers. */ 6562 1.1 mrg 6563 1.1 mrg struct shared_bitmap_hasher : free_ptr_hash <shared_bitmap_info> 6564 1.1 mrg { 6565 1.1 mrg static inline hashval_t hash (const shared_bitmap_info *); 6566 1.1 mrg static inline bool equal (const shared_bitmap_info *, 6567 1.1 mrg const shared_bitmap_info *); 6568 1.1 mrg }; 6569 1.1 mrg 6570 1.1 mrg /* Hash function for a shared_bitmap_info_t */ 6571 1.1 mrg 6572 1.1 mrg inline hashval_t 6573 1.1 mrg shared_bitmap_hasher::hash (const shared_bitmap_info *bi) 6574 1.1 mrg { 6575 1.1 mrg return bi->hashcode; 6576 1.1 mrg } 6577 1.1 mrg 6578 1.1 mrg /* Equality function for two shared_bitmap_info_t's. */ 6579 1.1 mrg 6580 1.1 mrg inline bool 6581 1.1 mrg shared_bitmap_hasher::equal (const shared_bitmap_info *sbi1, 6582 1.1 mrg const shared_bitmap_info *sbi2) 6583 1.1 mrg { 6584 1.1 mrg return bitmap_equal_p (sbi1->pt_vars, sbi2->pt_vars); 6585 1.1 mrg } 6586 1.1 mrg 6587 1.1 mrg /* Shared_bitmap hashtable. */ 6588 1.1 mrg 6589 1.1 mrg static hash_table<shared_bitmap_hasher> *shared_bitmap_table; 6590 1.1 mrg 6591 1.1 mrg /* Lookup a bitmap in the shared bitmap hashtable, and return an already 6592 1.1 mrg existing instance if there is one, NULL otherwise. */ 6593 1.1 mrg 6594 1.1 mrg static bitmap 6595 1.1 mrg shared_bitmap_lookup (bitmap pt_vars) 6596 1.1 mrg { 6597 1.1 mrg shared_bitmap_info **slot; 6598 1.1 mrg struct shared_bitmap_info sbi; 6599 1.1 mrg 6600 1.1 mrg sbi.pt_vars = pt_vars; 6601 1.1 mrg sbi.hashcode = bitmap_hash (pt_vars); 6602 1.1 mrg 6603 1.1 mrg slot = shared_bitmap_table->find_slot (&sbi, NO_INSERT); 6604 1.1 mrg if (!slot) 6605 1.1 mrg return NULL; 6606 1.1 mrg else 6607 1.1 mrg return (*slot)->pt_vars; 6608 1.1 mrg } 6609 1.1 mrg 6610 1.1 mrg 6611 1.1 mrg /* Add a bitmap to the shared bitmap hashtable. */ 6612 1.1 mrg 6613 1.1 mrg static void 6614 1.1 mrg shared_bitmap_add (bitmap pt_vars) 6615 1.1 mrg { 6616 1.1 mrg shared_bitmap_info **slot; 6617 1.1 mrg shared_bitmap_info_t sbi = XNEW (struct shared_bitmap_info); 6618 1.1 mrg 6619 1.1 mrg sbi->pt_vars = pt_vars; 6620 1.1 mrg sbi->hashcode = bitmap_hash (pt_vars); 6621 1.1 mrg 6622 1.1 mrg slot = shared_bitmap_table->find_slot (sbi, INSERT); 6623 1.1 mrg gcc_assert (!*slot); 6624 1.1 mrg *slot = sbi; 6625 1.1 mrg } 6626 1.1 mrg 6627 1.1 mrg 6628 1.1 mrg /* Set bits in INTO corresponding to the variable uids in solution set FROM. */ 6629 1.1 mrg 6630 1.1 mrg static void 6631 1.1 mrg set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt, 6632 1.1 mrg tree fndecl) 6633 1.1 mrg { 6634 1.1 mrg unsigned int i; 6635 1.1 mrg bitmap_iterator bi; 6636 1.1 mrg varinfo_t escaped_vi = get_varinfo (find (escaped_id)); 6637 1.1 mrg bool everything_escaped 6638 1.1 mrg = escaped_vi->solution && bitmap_bit_p (escaped_vi->solution, anything_id); 6639 1.1 mrg 6640 1.1 mrg EXECUTE_IF_SET_IN_BITMAP (from, 0, i, bi) 6641 1.1 mrg { 6642 1.1 mrg varinfo_t vi = get_varinfo (i); 6643 1.1 mrg 6644 1.1 mrg if (vi->is_artificial_var) 6645 1.1 mrg continue; 6646 1.1 mrg 6647 1.1 mrg if (everything_escaped 6648 1.1 mrg || (escaped_vi->solution 6649 1.1 mrg && bitmap_bit_p (escaped_vi->solution, i))) 6650 1.1 mrg { 6651 1.1 mrg pt->vars_contains_escaped = true; 6652 1.1 mrg pt->vars_contains_escaped_heap |= vi->is_heap_var; 6653 1.1 mrg } 6654 1.1 mrg 6655 1.1 mrg if (vi->is_restrict_var) 6656 1.1 mrg pt->vars_contains_restrict = true; 6657 1.1 mrg 6658 1.1 mrg if (VAR_P (vi->decl) 6659 1.1 mrg || TREE_CODE (vi->decl) == PARM_DECL 6660 1.1 mrg || TREE_CODE (vi->decl) == RESULT_DECL) 6661 1.1 mrg { 6662 1.1 mrg /* If we are in IPA mode we will not recompute points-to 6663 1.1 mrg sets after inlining so make sure they stay valid. */ 6664 1.1 mrg if (in_ipa_mode 6665 1.1 mrg && !DECL_PT_UID_SET_P (vi->decl)) 6666 1.1 mrg SET_DECL_PT_UID (vi->decl, DECL_UID (vi->decl)); 6667 1.1 mrg 6668 1.1 mrg /* Add the decl to the points-to set. Note that the points-to 6669 1.1 mrg set contains global variables. */ 6670 1.1 mrg bitmap_set_bit (into, DECL_PT_UID (vi->decl)); 6671 1.1 mrg if (vi->is_global_var 6672 1.1 mrg /* In IPA mode the escaped_heap trick doesn't work as 6673 1.1 mrg ESCAPED is escaped from the unit but 6674 1.1 mrg pt_solution_includes_global needs to answer true for 6675 1.1 mrg all variables not automatic within a function. 6676 1.1 mrg For the same reason is_global_var is not the 6677 1.1 mrg correct flag to track - local variables from other 6678 1.1 mrg functions also need to be considered global. 6679 1.1 mrg Conveniently all HEAP vars are not put in function 6680 1.1 mrg scope. */ 6681 1.1 mrg || (in_ipa_mode 6682 1.1 mrg && fndecl 6683 1.1 mrg && ! auto_var_in_fn_p (vi->decl, fndecl))) 6684 1.1 mrg pt->vars_contains_nonlocal = true; 6685 1.1 mrg 6686 1.1 mrg /* If we have a variable that is interposable record that fact 6687 1.1 mrg for pointer comparison simplification. */ 6688 1.1 mrg if (VAR_P (vi->decl) 6689 1.1 mrg && (TREE_STATIC (vi->decl) || DECL_EXTERNAL (vi->decl)) 6690 1.1 mrg && ! decl_binds_to_current_def_p (vi->decl)) 6691 1.1 mrg pt->vars_contains_interposable = true; 6692 1.1 mrg 6693 1.1 mrg /* If this is a local variable we can have overlapping lifetime 6694 1.1 mrg of different function invocations through recursion duplicate 6695 1.1 mrg it with its shadow variable. */ 6696 1.1 mrg if (in_ipa_mode 6697 1.1 mrg && vi->shadow_var_uid != 0) 6698 1.1 mrg { 6699 1.1 mrg bitmap_set_bit (into, vi->shadow_var_uid); 6700 1.1 mrg pt->vars_contains_nonlocal = true; 6701 1.1 mrg } 6702 1.1 mrg } 6703 1.1 mrg 6704 1.1 mrg else if (TREE_CODE (vi->decl) == FUNCTION_DECL 6705 1.1 mrg || TREE_CODE (vi->decl) == LABEL_DECL) 6706 1.1 mrg { 6707 1.1 mrg /* Nothing should read/write from/to code so we can 6708 1.1 mrg save bits by not including them in the points-to bitmaps. 6709 1.1 mrg Still mark the points-to set as containing global memory 6710 1.1 mrg to make code-patching possible - see PR70128. */ 6711 1.1 mrg pt->vars_contains_nonlocal = true; 6712 1.1 mrg } 6713 1.1 mrg } 6714 1.1 mrg } 6715 1.1 mrg 6716 1.1 mrg 6717 1.1 mrg /* Compute the points-to solution *PT for the variable VI. */ 6718 1.1 mrg 6719 1.1 mrg static struct pt_solution 6720 1.1 mrg find_what_var_points_to (tree fndecl, varinfo_t orig_vi) 6721 1.1 mrg { 6722 1.1 mrg unsigned int i; 6723 1.1 mrg bitmap_iterator bi; 6724 1.1 mrg bitmap finished_solution; 6725 1.1 mrg bitmap result; 6726 1.1 mrg varinfo_t vi; 6727 1.1 mrg struct pt_solution *pt; 6728 1.1 mrg 6729 1.1 mrg /* This variable may have been collapsed, let's get the real 6730 1.1 mrg variable. */ 6731 1.1 mrg vi = get_varinfo (find (orig_vi->id)); 6732 1.1 mrg 6733 1.1 mrg /* See if we have already computed the solution and return it. */ 6734 1.1 mrg pt_solution **slot = &final_solutions->get_or_insert (vi); 6735 1.1 mrg if (*slot != NULL) 6736 1.1 mrg return **slot; 6737 1.1 mrg 6738 1.1 mrg *slot = pt = XOBNEW (&final_solutions_obstack, struct pt_solution); 6739 1.1 mrg memset (pt, 0, sizeof (struct pt_solution)); 6740 1.1 mrg 6741 1.1 mrg /* Translate artificial variables into SSA_NAME_PTR_INFO 6742 1.1 mrg attributes. */ 6743 1.1 mrg EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi) 6744 1.1 mrg { 6745 1.1 mrg varinfo_t vi = get_varinfo (i); 6746 1.1 mrg 6747 1.1 mrg if (vi->is_artificial_var) 6748 1.1 mrg { 6749 1.1 mrg if (vi->id == nothing_id) 6750 1.1 mrg pt->null = 1; 6751 1.1 mrg else if (vi->id == escaped_id) 6752 1.1 mrg { 6753 1.1 mrg if (in_ipa_mode) 6754 1.1 mrg pt->ipa_escaped = 1; 6755 1.1 mrg else 6756 1.1 mrg pt->escaped = 1; 6757 1.1 mrg /* Expand some special vars of ESCAPED in-place here. */ 6758 1.1 mrg varinfo_t evi = get_varinfo (find (escaped_id)); 6759 1.1 mrg if (bitmap_bit_p (evi->solution, nonlocal_id)) 6760 1.1 mrg pt->nonlocal = 1; 6761 1.1 mrg } 6762 1.1 mrg else if (vi->id == nonlocal_id) 6763 1.1 mrg pt->nonlocal = 1; 6764 1.1 mrg else if (vi->id == string_id) 6765 1.1 mrg /* Nobody cares - STRING_CSTs are read-only entities. */ 6766 1.1 mrg ; 6767 1.1 mrg else if (vi->id == anything_id 6768 1.1 mrg || vi->id == integer_id) 6769 1.1 mrg pt->anything = 1; 6770 1.1 mrg } 6771 1.1 mrg } 6772 1.1 mrg 6773 1.1 mrg /* Instead of doing extra work, simply do not create 6774 1.1 mrg elaborate points-to information for pt_anything pointers. */ 6775 1.1 mrg if (pt->anything) 6776 1.1 mrg return *pt; 6777 1.1 mrg 6778 1.1 mrg /* Share the final set of variables when possible. */ 6779 1.1 mrg finished_solution = BITMAP_GGC_ALLOC (); 6780 1.1 mrg stats.points_to_sets_created++; 6781 1.1 mrg 6782 1.1 mrg set_uids_in_ptset (finished_solution, vi->solution, pt, fndecl); 6783 1.1 mrg result = shared_bitmap_lookup (finished_solution); 6784 1.1 mrg if (!result) 6785 1.1 mrg { 6786 1.1 mrg shared_bitmap_add (finished_solution); 6787 1.1 mrg pt->vars = finished_solution; 6788 1.1 mrg } 6789 1.1 mrg else 6790 1.1 mrg { 6791 1.1 mrg pt->vars = result; 6792 1.1 mrg bitmap_clear (finished_solution); 6793 1.1 mrg } 6794 1.1 mrg 6795 1.1 mrg return *pt; 6796 1.1 mrg } 6797 1.1 mrg 6798 1.1 mrg /* Given a pointer variable P, fill in its points-to set. */ 6799 1.1 mrg 6800 1.1 mrg static void 6801 1.1 mrg find_what_p_points_to (tree fndecl, tree p) 6802 1.1 mrg { 6803 1.1 mrg struct ptr_info_def *pi; 6804 1.1 mrg tree lookup_p = p; 6805 1.1 mrg varinfo_t vi; 6806 1.1 mrg value_range vr; 6807 1.1 mrg get_range_query (DECL_STRUCT_FUNCTION (fndecl))->range_of_expr (vr, p); 6808 1.1 mrg bool nonnull = vr.nonzero_p (); 6809 1.1 mrg 6810 1.1 mrg /* For parameters, get at the points-to set for the actual parm 6811 1.1 mrg decl. */ 6812 1.1 mrg if (TREE_CODE (p) == SSA_NAME 6813 1.1 mrg && SSA_NAME_IS_DEFAULT_DEF (p) 6814 1.1 mrg && (TREE_CODE (SSA_NAME_VAR (p)) == PARM_DECL 6815 1.1 mrg || TREE_CODE (SSA_NAME_VAR (p)) == RESULT_DECL)) 6816 1.1 mrg lookup_p = SSA_NAME_VAR (p); 6817 1.1 mrg 6818 1.1 mrg vi = lookup_vi_for_tree (lookup_p); 6819 1.1 mrg if (!vi) 6820 1.1 mrg return; 6821 1.1 mrg 6822 1.1 mrg pi = get_ptr_info (p); 6823 1.1 mrg pi->pt = find_what_var_points_to (fndecl, vi); 6824 1.1 mrg /* Conservatively set to NULL from PTA (to true). */ 6825 1.1 mrg pi->pt.null = 1; 6826 1.1 mrg /* Preserve pointer nonnull globally computed. */ 6827 1.1 mrg if (nonnull) 6828 1.1 mrg set_ptr_nonnull (p); 6829 1.1 mrg } 6830 1.1 mrg 6831 1.1 mrg 6832 1.1 mrg /* Query statistics for points-to solutions. */ 6833 1.1 mrg 6834 1.1 mrg static struct { 6835 1.1 mrg unsigned HOST_WIDE_INT pt_solution_includes_may_alias; 6836 1.1 mrg unsigned HOST_WIDE_INT pt_solution_includes_no_alias; 6837 1.1 mrg unsigned HOST_WIDE_INT pt_solutions_intersect_may_alias; 6838 1.1 mrg unsigned HOST_WIDE_INT pt_solutions_intersect_no_alias; 6839 1.1 mrg } pta_stats; 6840 1.1 mrg 6841 1.1 mrg void 6842 1.1 mrg dump_pta_stats (FILE *s) 6843 1.1 mrg { 6844 1.1 mrg fprintf (s, "\nPTA query stats:\n"); 6845 1.1 mrg fprintf (s, " pt_solution_includes: " 6846 1.1 mrg HOST_WIDE_INT_PRINT_DEC" disambiguations, " 6847 1.1 mrg HOST_WIDE_INT_PRINT_DEC" queries\n", 6848 1.1 mrg pta_stats.pt_solution_includes_no_alias, 6849 1.1 mrg pta_stats.pt_solution_includes_no_alias 6850 1.1 mrg + pta_stats.pt_solution_includes_may_alias); 6851 1.1 mrg fprintf (s, " pt_solutions_intersect: " 6852 1.1 mrg HOST_WIDE_INT_PRINT_DEC" disambiguations, " 6853 1.1 mrg HOST_WIDE_INT_PRINT_DEC" queries\n", 6854 1.1 mrg pta_stats.pt_solutions_intersect_no_alias, 6855 1.1 mrg pta_stats.pt_solutions_intersect_no_alias 6856 1.1 mrg + pta_stats.pt_solutions_intersect_may_alias); 6857 1.1 mrg } 6858 1.1 mrg 6859 1.1 mrg 6860 1.1 mrg /* Reset the points-to solution *PT to a conservative default 6861 1.1 mrg (point to anything). */ 6862 1.1 mrg 6863 1.1 mrg void 6864 1.1 mrg pt_solution_reset (struct pt_solution *pt) 6865 1.1 mrg { 6866 1.1 mrg memset (pt, 0, sizeof (struct pt_solution)); 6867 1.1 mrg pt->anything = true; 6868 1.1 mrg pt->null = true; 6869 1.1 mrg } 6870 1.1 mrg 6871 1.1 mrg /* Set the points-to solution *PT to point only to the variables 6872 1.1 mrg in VARS. VARS_CONTAINS_GLOBAL specifies whether that contains 6873 1.1 mrg global variables and VARS_CONTAINS_RESTRICT specifies whether 6874 1.1 mrg it contains restrict tag variables. */ 6875 1.1 mrg 6876 1.1 mrg void 6877 1.1 mrg pt_solution_set (struct pt_solution *pt, bitmap vars, 6878 1.1 mrg bool vars_contains_nonlocal) 6879 1.1 mrg { 6880 1.1 mrg memset (pt, 0, sizeof (struct pt_solution)); 6881 1.1 mrg pt->vars = vars; 6882 1.1 mrg pt->vars_contains_nonlocal = vars_contains_nonlocal; 6883 1.1 mrg pt->vars_contains_escaped 6884 1.1 mrg = (cfun->gimple_df->escaped.anything 6885 1.1 mrg || bitmap_intersect_p (cfun->gimple_df->escaped.vars, vars)); 6886 1.1 mrg } 6887 1.1 mrg 6888 1.1 mrg /* Set the points-to solution *PT to point only to the variable VAR. */ 6889 1.1 mrg 6890 1.1 mrg void 6891 1.1 mrg pt_solution_set_var (struct pt_solution *pt, tree var) 6892 1.1 mrg { 6893 1.1 mrg memset (pt, 0, sizeof (struct pt_solution)); 6894 1.1 mrg pt->vars = BITMAP_GGC_ALLOC (); 6895 1.1 mrg bitmap_set_bit (pt->vars, DECL_PT_UID (var)); 6896 1.1 mrg pt->vars_contains_nonlocal = is_global_var (var); 6897 1.1 mrg pt->vars_contains_escaped 6898 1.1 mrg = (cfun->gimple_df->escaped.anything 6899 1.1 mrg || bitmap_bit_p (cfun->gimple_df->escaped.vars, DECL_PT_UID (var))); 6900 1.1 mrg } 6901 1.1 mrg 6902 1.1 mrg /* Computes the union of the points-to solutions *DEST and *SRC and 6903 1.1 mrg stores the result in *DEST. This changes the points-to bitmap 6904 1.1 mrg of *DEST and thus may not be used if that might be shared. 6905 1.1 mrg The points-to bitmap of *SRC and *DEST will not be shared after 6906 1.1 mrg this function if they were not before. */ 6907 1.1 mrg 6908 1.1 mrg static void 6909 1.1 mrg pt_solution_ior_into (struct pt_solution *dest, struct pt_solution *src) 6910 1.1 mrg { 6911 1.1 mrg dest->anything |= src->anything; 6912 1.1 mrg if (dest->anything) 6913 1.1 mrg { 6914 1.1 mrg pt_solution_reset (dest); 6915 1.1 mrg return; 6916 1.1 mrg } 6917 1.1 mrg 6918 1.1 mrg dest->nonlocal |= src->nonlocal; 6919 1.1 mrg dest->escaped |= src->escaped; 6920 1.1 mrg dest->ipa_escaped |= src->ipa_escaped; 6921 1.1 mrg dest->null |= src->null; 6922 1.1 mrg dest->vars_contains_nonlocal |= src->vars_contains_nonlocal; 6923 1.1 mrg dest->vars_contains_escaped |= src->vars_contains_escaped; 6924 1.1 mrg dest->vars_contains_escaped_heap |= src->vars_contains_escaped_heap; 6925 1.1 mrg if (!src->vars) 6926 1.1 mrg return; 6927 1.1 mrg 6928 1.1 mrg if (!dest->vars) 6929 1.1 mrg dest->vars = BITMAP_GGC_ALLOC (); 6930 1.1 mrg bitmap_ior_into (dest->vars, src->vars); 6931 1.1 mrg } 6932 1.1 mrg 6933 1.1 mrg /* Return true if the points-to solution *PT is empty. */ 6934 1.1 mrg 6935 1.1 mrg bool 6936 1.1 mrg pt_solution_empty_p (const pt_solution *pt) 6937 1.1 mrg { 6938 1.1 mrg if (pt->anything 6939 1.1 mrg || pt->nonlocal) 6940 1.1 mrg return false; 6941 1.1 mrg 6942 1.1 mrg if (pt->vars 6943 1.1 mrg && !bitmap_empty_p (pt->vars)) 6944 1.1 mrg return false; 6945 1.1 mrg 6946 1.1 mrg /* If the solution includes ESCAPED, check if that is empty. */ 6947 1.1 mrg if (pt->escaped 6948 1.1 mrg && !pt_solution_empty_p (&cfun->gimple_df->escaped)) 6949 1.1 mrg return false; 6950 1.1 mrg 6951 1.1 mrg /* If the solution includes ESCAPED, check if that is empty. */ 6952 1.1 mrg if (pt->ipa_escaped 6953 1.1 mrg && !pt_solution_empty_p (&ipa_escaped_pt)) 6954 1.1 mrg return false; 6955 1.1 mrg 6956 1.1 mrg return true; 6957 1.1 mrg } 6958 1.1 mrg 6959 1.1 mrg /* Return true if the points-to solution *PT only point to a single var, and 6960 1.1 mrg return the var uid in *UID. */ 6961 1.1 mrg 6962 1.1 mrg bool 6963 1.1 mrg pt_solution_singleton_or_null_p (struct pt_solution *pt, unsigned *uid) 6964 1.1 mrg { 6965 1.1 mrg if (pt->anything || pt->nonlocal || pt->escaped || pt->ipa_escaped 6966 1.1 mrg || pt->vars == NULL 6967 1.1 mrg || !bitmap_single_bit_set_p (pt->vars)) 6968 1.1 mrg return false; 6969 1.1 mrg 6970 1.1 mrg *uid = bitmap_first_set_bit (pt->vars); 6971 1.1 mrg return true; 6972 1.1 mrg } 6973 1.1 mrg 6974 1.1 mrg /* Return true if the points-to solution *PT includes global memory. 6975 1.1 mrg If ESCAPED_LOCAL_P is true then escaped local variables are also 6976 1.1 mrg considered global. */ 6977 1.1 mrg 6978 1.1 mrg bool 6979 1.1 mrg pt_solution_includes_global (struct pt_solution *pt, bool escaped_local_p) 6980 1.1 mrg { 6981 1.1 mrg if (pt->anything 6982 1.1 mrg || pt->nonlocal 6983 1.1 mrg || pt->vars_contains_nonlocal 6984 1.1 mrg /* The following is a hack to make the malloc escape hack work. 6985 1.1 mrg In reality we'd need different sets for escaped-through-return 6986 1.1 mrg and escaped-to-callees and passes would need to be updated. */ 6987 1.1 mrg || pt->vars_contains_escaped_heap) 6988 1.1 mrg return true; 6989 1.1 mrg 6990 1.1 mrg if (escaped_local_p && pt->vars_contains_escaped) 6991 1.1 mrg return true; 6992 1.1 mrg 6993 1.1 mrg /* 'escaped' is also a placeholder so we have to look into it. */ 6994 1.1 mrg if (pt->escaped) 6995 1.1 mrg return pt_solution_includes_global (&cfun->gimple_df->escaped, 6996 1.1 mrg escaped_local_p); 6997 1.1 mrg 6998 1.1 mrg if (pt->ipa_escaped) 6999 1.1 mrg return pt_solution_includes_global (&ipa_escaped_pt, 7000 1.1 mrg escaped_local_p); 7001 1.1 mrg 7002 1.1 mrg return false; 7003 1.1 mrg } 7004 1.1 mrg 7005 1.1 mrg /* Return true if the points-to solution *PT includes the variable 7006 1.1 mrg declaration DECL. */ 7007 1.1 mrg 7008 1.1 mrg static bool 7009 1.1 mrg pt_solution_includes_1 (struct pt_solution *pt, const_tree decl) 7010 1.1 mrg { 7011 1.1 mrg if (pt->anything) 7012 1.1 mrg return true; 7013 1.1 mrg 7014 1.1 mrg if (pt->nonlocal 7015 1.1 mrg && is_global_var (decl)) 7016 1.1 mrg return true; 7017 1.1 mrg 7018 1.1 mrg if (pt->vars 7019 1.1 mrg && bitmap_bit_p (pt->vars, DECL_PT_UID (decl))) 7020 1.1 mrg return true; 7021 1.1 mrg 7022 1.1 mrg /* If the solution includes ESCAPED, check it. */ 7023 1.1 mrg if (pt->escaped 7024 1.1 mrg && pt_solution_includes_1 (&cfun->gimple_df->escaped, decl)) 7025 1.1 mrg return true; 7026 1.1 mrg 7027 1.1 mrg /* If the solution includes ESCAPED, check it. */ 7028 1.1 mrg if (pt->ipa_escaped 7029 1.1 mrg && pt_solution_includes_1 (&ipa_escaped_pt, decl)) 7030 1.1 mrg return true; 7031 1.1 mrg 7032 1.1 mrg return false; 7033 1.1 mrg } 7034 1.1 mrg 7035 1.1 mrg bool 7036 1.1 mrg pt_solution_includes (struct pt_solution *pt, const_tree decl) 7037 1.1 mrg { 7038 1.1 mrg bool res = pt_solution_includes_1 (pt, decl); 7039 1.1 mrg if (res) 7040 1.1 mrg ++pta_stats.pt_solution_includes_may_alias; 7041 1.1 mrg else 7042 1.1 mrg ++pta_stats.pt_solution_includes_no_alias; 7043 1.1 mrg return res; 7044 1.1 mrg } 7045 1.1 mrg 7046 1.1 mrg /* Return true if both points-to solutions PT1 and PT2 have a non-empty 7047 1.1 mrg intersection. */ 7048 1.1 mrg 7049 1.1 mrg static bool 7050 1.1 mrg pt_solutions_intersect_1 (struct pt_solution *pt1, struct pt_solution *pt2) 7051 1.1 mrg { 7052 1.1 mrg if (pt1->anything || pt2->anything) 7053 1.1 mrg return true; 7054 1.1 mrg 7055 1.1 mrg /* If either points to unknown global memory and the other points to 7056 1.1 mrg any global memory they alias. */ 7057 1.1 mrg if ((pt1->nonlocal 7058 1.1 mrg && (pt2->nonlocal 7059 1.1 mrg || pt2->vars_contains_nonlocal)) 7060 1.1 mrg || (pt2->nonlocal 7061 1.1 mrg && pt1->vars_contains_nonlocal)) 7062 1.1 mrg return true; 7063 1.1 mrg 7064 1.1 mrg /* If either points to all escaped memory and the other points to 7065 1.1 mrg any escaped memory they alias. */ 7066 1.1 mrg if ((pt1->escaped 7067 1.1 mrg && (pt2->escaped 7068 1.1 mrg || pt2->vars_contains_escaped)) 7069 1.1 mrg || (pt2->escaped 7070 1.1 mrg && pt1->vars_contains_escaped)) 7071 1.1 mrg return true; 7072 1.1 mrg 7073 1.1 mrg /* Check the escaped solution if required. 7074 1.1 mrg ??? Do we need to check the local against the IPA escaped sets? */ 7075 1.1 mrg if ((pt1->ipa_escaped || pt2->ipa_escaped) 7076 1.1 mrg && !pt_solution_empty_p (&ipa_escaped_pt)) 7077 1.1 mrg { 7078 1.1 mrg /* If both point to escaped memory and that solution 7079 1.1 mrg is not empty they alias. */ 7080 1.1 mrg if (pt1->ipa_escaped && pt2->ipa_escaped) 7081 1.1 mrg return true; 7082 1.1 mrg 7083 1.1 mrg /* If either points to escaped memory see if the escaped solution 7084 1.1 mrg intersects with the other. */ 7085 1.1 mrg if ((pt1->ipa_escaped 7086 1.1 mrg && pt_solutions_intersect_1 (&ipa_escaped_pt, pt2)) 7087 1.1 mrg || (pt2->ipa_escaped 7088 1.1 mrg && pt_solutions_intersect_1 (&ipa_escaped_pt, pt1))) 7089 1.1 mrg return true; 7090 1.1 mrg } 7091 1.1 mrg 7092 1.1 mrg /* Now both pointers alias if their points-to solution intersects. */ 7093 1.1 mrg return (pt1->vars 7094 1.1 mrg && pt2->vars 7095 1.1 mrg && bitmap_intersect_p (pt1->vars, pt2->vars)); 7096 1.1 mrg } 7097 1.1 mrg 7098 1.1 mrg bool 7099 1.1 mrg pt_solutions_intersect (struct pt_solution *pt1, struct pt_solution *pt2) 7100 1.1 mrg { 7101 1.1 mrg bool res = pt_solutions_intersect_1 (pt1, pt2); 7102 1.1 mrg if (res) 7103 1.1 mrg ++pta_stats.pt_solutions_intersect_may_alias; 7104 1.1 mrg else 7105 1.1 mrg ++pta_stats.pt_solutions_intersect_no_alias; 7106 1.1 mrg return res; 7107 1.1 mrg } 7108 1.1 mrg 7109 1.1 mrg 7110 1.1 mrg /* Dump points-to information to OUTFILE. */ 7111 1.1 mrg 7112 1.1 mrg static void 7113 1.1 mrg dump_sa_points_to_info (FILE *outfile) 7114 1.1 mrg { 7115 1.1 mrg unsigned int i; 7116 1.1 mrg 7117 1.1 mrg fprintf (outfile, "\nPoints-to sets\n\n"); 7118 1.1 mrg 7119 1.1 mrg if (dump_flags & TDF_STATS) 7120 1.1 mrg { 7121 1.1 mrg fprintf (outfile, "Stats:\n"); 7122 1.1 mrg fprintf (outfile, "Total vars: %d\n", stats.total_vars); 7123 1.1 mrg fprintf (outfile, "Non-pointer vars: %d\n", 7124 1.1 mrg stats.nonpointer_vars); 7125 1.1 mrg fprintf (outfile, "Statically unified vars: %d\n", 7126 1.1 mrg stats.unified_vars_static); 7127 1.1 mrg fprintf (outfile, "Dynamically unified vars: %d\n", 7128 1.1 mrg stats.unified_vars_dynamic); 7129 1.1 mrg fprintf (outfile, "Iterations: %d\n", stats.iterations); 7130 1.1 mrg fprintf (outfile, "Number of edges: %d\n", stats.num_edges); 7131 1.1 mrg fprintf (outfile, "Number of implicit edges: %d\n", 7132 1.1 mrg stats.num_implicit_edges); 7133 1.1 mrg } 7134 1.1 mrg 7135 1.1 mrg for (i = 1; i < varmap.length (); i++) 7136 1.1 mrg { 7137 1.1 mrg varinfo_t vi = get_varinfo (i); 7138 1.1 mrg if (!vi->may_have_pointers) 7139 1.1 mrg continue; 7140 1.1 mrg dump_solution_for_var (outfile, i); 7141 1.1 mrg } 7142 1.1 mrg } 7143 1.1 mrg 7144 1.1 mrg 7145 1.1 mrg /* Debug points-to information to stderr. */ 7146 1.1 mrg 7147 1.1 mrg DEBUG_FUNCTION void 7148 1.1 mrg debug_sa_points_to_info (void) 7149 1.1 mrg { 7150 1.1 mrg dump_sa_points_to_info (stderr); 7151 1.1 mrg } 7152 1.1 mrg 7153 1.1 mrg 7154 1.1 mrg /* Initialize the always-existing constraint variables for NULL 7155 1.1 mrg ANYTHING, READONLY, and INTEGER */ 7156 1.1 mrg 7157 1.1 mrg static void 7158 1.1 mrg init_base_vars (void) 7159 1.1 mrg { 7160 1.1 mrg struct constraint_expr lhs, rhs; 7161 1.1 mrg varinfo_t var_anything; 7162 1.1 mrg varinfo_t var_nothing; 7163 1.1 mrg varinfo_t var_string; 7164 1.1 mrg varinfo_t var_escaped; 7165 1.1 mrg varinfo_t var_nonlocal; 7166 1.1 mrg varinfo_t var_storedanything; 7167 1.1 mrg varinfo_t var_integer; 7168 1.1 mrg 7169 1.1 mrg /* Variable ID zero is reserved and should be NULL. */ 7170 1.1 mrg varmap.safe_push (NULL); 7171 1.1 mrg 7172 1.1 mrg /* Create the NULL variable, used to represent that a variable points 7173 1.1 mrg to NULL. */ 7174 1.1 mrg var_nothing = new_var_info (NULL_TREE, "NULL", false); 7175 1.1 mrg gcc_assert (var_nothing->id == nothing_id); 7176 1.1 mrg var_nothing->is_artificial_var = 1; 7177 1.1 mrg var_nothing->offset = 0; 7178 1.1 mrg var_nothing->size = ~0; 7179 1.1 mrg var_nothing->fullsize = ~0; 7180 1.1 mrg var_nothing->is_special_var = 1; 7181 1.1 mrg var_nothing->may_have_pointers = 0; 7182 1.1 mrg var_nothing->is_global_var = 0; 7183 1.1 mrg 7184 1.1 mrg /* Create the ANYTHING variable, used to represent that a variable 7185 1.1 mrg points to some unknown piece of memory. */ 7186 1.1 mrg var_anything = new_var_info (NULL_TREE, "ANYTHING", false); 7187 1.1 mrg gcc_assert (var_anything->id == anything_id); 7188 1.1 mrg var_anything->is_artificial_var = 1; 7189 1.1 mrg var_anything->size = ~0; 7190 1.1 mrg var_anything->offset = 0; 7191 1.1 mrg var_anything->fullsize = ~0; 7192 1.1 mrg var_anything->is_special_var = 1; 7193 1.1 mrg 7194 1.1 mrg /* Anything points to anything. This makes deref constraints just 7195 1.1 mrg work in the presence of linked list and other p = *p type loops, 7196 1.1 mrg by saying that *ANYTHING = ANYTHING. */ 7197 1.1 mrg lhs.type = SCALAR; 7198 1.1 mrg lhs.var = anything_id; 7199 1.1 mrg lhs.offset = 0; 7200 1.1 mrg rhs.type = ADDRESSOF; 7201 1.1 mrg rhs.var = anything_id; 7202 1.1 mrg rhs.offset = 0; 7203 1.1 mrg 7204 1.1 mrg /* This specifically does not use process_constraint because 7205 1.1 mrg process_constraint ignores all anything = anything constraints, since all 7206 1.1 mrg but this one are redundant. */ 7207 1.1 mrg constraints.safe_push (new_constraint (lhs, rhs)); 7208 1.1 mrg 7209 1.1 mrg /* Create the STRING variable, used to represent that a variable 7210 1.1 mrg points to a string literal. String literals don't contain 7211 1.1 mrg pointers so STRING doesn't point to anything. */ 7212 1.1 mrg var_string = new_var_info (NULL_TREE, "STRING", false); 7213 1.1 mrg gcc_assert (var_string->id == string_id); 7214 1.1 mrg var_string->is_artificial_var = 1; 7215 1.1 mrg var_string->offset = 0; 7216 1.1 mrg var_string->size = ~0; 7217 1.1 mrg var_string->fullsize = ~0; 7218 1.1 mrg var_string->is_special_var = 1; 7219 1.1 mrg var_string->may_have_pointers = 0; 7220 1.1 mrg 7221 1.1 mrg /* Create the ESCAPED variable, used to represent the set of escaped 7222 1.1 mrg memory. */ 7223 1.1 mrg var_escaped = new_var_info (NULL_TREE, "ESCAPED", false); 7224 1.1 mrg gcc_assert (var_escaped->id == escaped_id); 7225 1.1 mrg var_escaped->is_artificial_var = 1; 7226 1.1 mrg var_escaped->offset = 0; 7227 1.1 mrg var_escaped->size = ~0; 7228 1.1 mrg var_escaped->fullsize = ~0; 7229 1.1 mrg var_escaped->is_special_var = 0; 7230 1.1 mrg 7231 1.1 mrg /* Create the NONLOCAL variable, used to represent the set of nonlocal 7232 1.1 mrg memory. */ 7233 1.1 mrg var_nonlocal = new_var_info (NULL_TREE, "NONLOCAL", false); 7234 1.1 mrg gcc_assert (var_nonlocal->id == nonlocal_id); 7235 1.1 mrg var_nonlocal->is_artificial_var = 1; 7236 1.1 mrg var_nonlocal->offset = 0; 7237 1.1 mrg var_nonlocal->size = ~0; 7238 1.1 mrg var_nonlocal->fullsize = ~0; 7239 1.1 mrg var_nonlocal->is_special_var = 1; 7240 1.1 mrg 7241 1.1 mrg /* ESCAPED = *ESCAPED, because escaped is may-deref'd at calls, etc. */ 7242 1.1 mrg lhs.type = SCALAR; 7243 1.1 mrg lhs.var = escaped_id; 7244 1.1 mrg lhs.offset = 0; 7245 1.1 mrg rhs.type = DEREF; 7246 1.1 mrg rhs.var = escaped_id; 7247 1.1 mrg rhs.offset = 0; 7248 1.1 mrg process_constraint (new_constraint (lhs, rhs)); 7249 1.1 mrg 7250 1.1 mrg /* ESCAPED = ESCAPED + UNKNOWN_OFFSET, because if a sub-field escapes the 7251 1.1 mrg whole variable escapes. */ 7252 1.1 mrg lhs.type = SCALAR; 7253 1.1 mrg lhs.var = escaped_id; 7254 1.1 mrg lhs.offset = 0; 7255 1.1 mrg rhs.type = SCALAR; 7256 1.1 mrg rhs.var = escaped_id; 7257 1.1 mrg rhs.offset = UNKNOWN_OFFSET; 7258 1.1 mrg process_constraint (new_constraint (lhs, rhs)); 7259 1.1 mrg 7260 1.1 mrg /* *ESCAPED = NONLOCAL. This is true because we have to assume 7261 1.1 mrg everything pointed to by escaped points to what global memory can 7262 1.1 mrg point to. */ 7263 1.1 mrg lhs.type = DEREF; 7264 1.1 mrg lhs.var = escaped_id; 7265 1.1 mrg lhs.offset = 0; 7266 1.1 mrg rhs.type = SCALAR; 7267 1.1 mrg rhs.var = nonlocal_id; 7268 1.1 mrg rhs.offset = 0; 7269 1.1 mrg process_constraint (new_constraint (lhs, rhs)); 7270 1.1 mrg 7271 1.1 mrg /* NONLOCAL = &NONLOCAL, NONLOCAL = &ESCAPED. This is true because 7272 1.1 mrg global memory may point to global memory and escaped memory. */ 7273 1.1 mrg lhs.type = SCALAR; 7274 1.1 mrg lhs.var = nonlocal_id; 7275 1.1 mrg lhs.offset = 0; 7276 1.1 mrg rhs.type = ADDRESSOF; 7277 1.1 mrg rhs.var = nonlocal_id; 7278 1.1 mrg rhs.offset = 0; 7279 1.1 mrg process_constraint (new_constraint (lhs, rhs)); 7280 1.1 mrg rhs.type = ADDRESSOF; 7281 1.1 mrg rhs.var = escaped_id; 7282 1.1 mrg rhs.offset = 0; 7283 1.1 mrg process_constraint (new_constraint (lhs, rhs)); 7284 1.1 mrg 7285 1.1 mrg /* Create the STOREDANYTHING variable, used to represent the set of 7286 1.1 mrg variables stored to *ANYTHING. */ 7287 1.1 mrg var_storedanything = new_var_info (NULL_TREE, "STOREDANYTHING", false); 7288 1.1 mrg gcc_assert (var_storedanything->id == storedanything_id); 7289 1.1 mrg var_storedanything->is_artificial_var = 1; 7290 1.1 mrg var_storedanything->offset = 0; 7291 1.1 mrg var_storedanything->size = ~0; 7292 1.1 mrg var_storedanything->fullsize = ~0; 7293 1.1 mrg var_storedanything->is_special_var = 0; 7294 1.1 mrg 7295 1.1 mrg /* Create the INTEGER variable, used to represent that a variable points 7296 1.1 mrg to what an INTEGER "points to". */ 7297 1.1 mrg var_integer = new_var_info (NULL_TREE, "INTEGER", false); 7298 1.1 mrg gcc_assert (var_integer->id == integer_id); 7299 1.1 mrg var_integer->is_artificial_var = 1; 7300 1.1 mrg var_integer->size = ~0; 7301 1.1 mrg var_integer->fullsize = ~0; 7302 1.1 mrg var_integer->offset = 0; 7303 1.1 mrg var_integer->is_special_var = 1; 7304 1.1 mrg 7305 1.1 mrg /* INTEGER = ANYTHING, because we don't know where a dereference of 7306 1.1 mrg a random integer will point to. */ 7307 1.1 mrg lhs.type = SCALAR; 7308 1.1 mrg lhs.var = integer_id; 7309 1.1 mrg lhs.offset = 0; 7310 1.1 mrg rhs.type = ADDRESSOF; 7311 1.1 mrg rhs.var = anything_id; 7312 1.1 mrg rhs.offset = 0; 7313 1.1 mrg process_constraint (new_constraint (lhs, rhs)); 7314 1.1 mrg } 7315 1.1 mrg 7316 1.1 mrg /* Initialize things necessary to perform PTA */ 7317 1.1 mrg 7318 1.1 mrg static void 7319 1.1 mrg init_alias_vars (void) 7320 1.1 mrg { 7321 1.1 mrg use_field_sensitive = (param_max_fields_for_field_sensitive > 1); 7322 1.1 mrg 7323 1.1 mrg bitmap_obstack_initialize (&pta_obstack); 7324 1.1 mrg bitmap_obstack_initialize (&oldpta_obstack); 7325 1.1 mrg bitmap_obstack_initialize (&predbitmap_obstack); 7326 1.1 mrg 7327 1.1 mrg constraints.create (8); 7328 1.1 mrg varmap.create (8); 7329 1.1 mrg vi_for_tree = new hash_map<tree, varinfo_t>; 7330 1.1 mrg call_stmt_vars = new hash_map<gimple *, varinfo_t>; 7331 1.1 mrg 7332 1.1 mrg memset (&stats, 0, sizeof (stats)); 7333 1.1 mrg shared_bitmap_table = new hash_table<shared_bitmap_hasher> (511); 7334 1.1 mrg init_base_vars (); 7335 1.1 mrg 7336 1.1 mrg gcc_obstack_init (&fake_var_decl_obstack); 7337 1.1 mrg 7338 1.1 mrg final_solutions = new hash_map<varinfo_t, pt_solution *>; 7339 1.1 mrg gcc_obstack_init (&final_solutions_obstack); 7340 1.1 mrg } 7341 1.1 mrg 7342 1.1 mrg /* Remove the REF and ADDRESS edges from GRAPH, as well as all the 7343 1.1 mrg predecessor edges. */ 7344 1.1 mrg 7345 1.1 mrg static void 7346 1.1 mrg remove_preds_and_fake_succs (constraint_graph_t graph) 7347 1.1 mrg { 7348 1.1 mrg unsigned int i; 7349 1.1 mrg 7350 1.1 mrg /* Clear the implicit ref and address nodes from the successor 7351 1.1 mrg lists. */ 7352 1.1 mrg for (i = 1; i < FIRST_REF_NODE; i++) 7353 1.1 mrg { 7354 1.1 mrg if (graph->succs[i]) 7355 1.1 mrg bitmap_clear_range (graph->succs[i], FIRST_REF_NODE, 7356 1.1 mrg FIRST_REF_NODE * 2); 7357 1.1 mrg } 7358 1.1 mrg 7359 1.1 mrg /* Free the successor list for the non-ref nodes. */ 7360 1.1 mrg for (i = FIRST_REF_NODE + 1; i < graph->size; i++) 7361 1.1 mrg { 7362 1.1 mrg if (graph->succs[i]) 7363 1.1 mrg BITMAP_FREE (graph->succs[i]); 7364 1.1 mrg } 7365 1.1 mrg 7366 1.1 mrg /* Now reallocate the size of the successor list as, and blow away 7367 1.1 mrg the predecessor bitmaps. */ 7368 1.1 mrg graph->size = varmap.length (); 7369 1.1 mrg graph->succs = XRESIZEVEC (bitmap, graph->succs, graph->size); 7370 1.1 mrg 7371 1.1 mrg free (graph->implicit_preds); 7372 1.1 mrg graph->implicit_preds = NULL; 7373 1.1 mrg free (graph->preds); 7374 1.1 mrg graph->preds = NULL; 7375 1.1 mrg bitmap_obstack_release (&predbitmap_obstack); 7376 1.1 mrg } 7377 1.1 mrg 7378 1.1 mrg /* Solve the constraint set. */ 7379 1.1 mrg 7380 1.1 mrg static void 7381 1.1 mrg solve_constraints (void) 7382 1.1 mrg { 7383 1.1 mrg class scc_info *si; 7384 1.1 mrg 7385 1.1 mrg /* Sort varinfos so that ones that cannot be pointed to are last. 7386 1.1 mrg This makes bitmaps more efficient. */ 7387 1.1 mrg unsigned int *map = XNEWVEC (unsigned int, varmap.length ()); 7388 1.1 mrg for (unsigned i = 0; i < integer_id + 1; ++i) 7389 1.1 mrg map[i] = i; 7390 1.1 mrg /* Start with address-taken vars, followed by not address-taken vars 7391 1.1 mrg to move vars never appearing in the points-to solution bitmaps last. */ 7392 1.1 mrg unsigned j = integer_id + 1; 7393 1.1 mrg for (unsigned i = integer_id + 1; i < varmap.length (); ++i) 7394 1.1 mrg if (varmap[varmap[i]->head]->address_taken) 7395 1.1 mrg map[i] = j++; 7396 1.1 mrg for (unsigned i = integer_id + 1; i < varmap.length (); ++i) 7397 1.1 mrg if (! varmap[varmap[i]->head]->address_taken) 7398 1.1 mrg map[i] = j++; 7399 1.1 mrg /* Shuffle varmap according to map. */ 7400 1.1 mrg for (unsigned i = integer_id + 1; i < varmap.length (); ++i) 7401 1.1 mrg { 7402 1.1 mrg while (map[varmap[i]->id] != i) 7403 1.1 mrg std::swap (varmap[i], varmap[map[varmap[i]->id]]); 7404 1.1 mrg gcc_assert (bitmap_empty_p (varmap[i]->solution)); 7405 1.1 mrg varmap[i]->id = i; 7406 1.1 mrg varmap[i]->next = map[varmap[i]->next]; 7407 1.1 mrg varmap[i]->head = map[varmap[i]->head]; 7408 1.1 mrg } 7409 1.1 mrg /* Finally rewrite constraints. */ 7410 1.1 mrg for (unsigned i = 0; i < constraints.length (); ++i) 7411 1.1 mrg { 7412 1.1 mrg constraints[i]->lhs.var = map[constraints[i]->lhs.var]; 7413 1.1 mrg constraints[i]->rhs.var = map[constraints[i]->rhs.var]; 7414 1.1 mrg } 7415 1.1 mrg free (map); 7416 1.1 mrg 7417 1.1 mrg if (dump_file) 7418 1.1 mrg fprintf (dump_file, 7419 1.1 mrg "\nCollapsing static cycles and doing variable " 7420 1.1 mrg "substitution\n"); 7421 1.1 mrg 7422 1.1 mrg init_graph (varmap.length () * 2); 7423 1.1 mrg 7424 1.1 mrg if (dump_file) 7425 1.1 mrg fprintf (dump_file, "Building predecessor graph\n"); 7426 1.1 mrg build_pred_graph (); 7427 1.1 mrg 7428 1.1 mrg if (dump_file) 7429 1.1 mrg fprintf (dump_file, "Detecting pointer and location " 7430 1.1 mrg "equivalences\n"); 7431 1.1 mrg si = perform_var_substitution (graph); 7432 1.1 mrg 7433 1.1 mrg if (dump_file) 7434 1.1 mrg fprintf (dump_file, "Rewriting constraints and unifying " 7435 1.1 mrg "variables\n"); 7436 1.1 mrg rewrite_constraints (graph, si); 7437 1.1 mrg 7438 1.1 mrg build_succ_graph (); 7439 1.1 mrg 7440 1.1 mrg free_var_substitution_info (si); 7441 1.1 mrg 7442 1.1 mrg /* Attach complex constraints to graph nodes. */ 7443 1.1 mrg move_complex_constraints (graph); 7444 1.1 mrg 7445 1.1 mrg if (dump_file) 7446 1.1 mrg fprintf (dump_file, "Uniting pointer but not location equivalent " 7447 1.1 mrg "variables\n"); 7448 1.1 mrg unite_pointer_equivalences (graph); 7449 1.1 mrg 7450 1.1 mrg if (dump_file) 7451 1.1 mrg fprintf (dump_file, "Finding indirect cycles\n"); 7452 1.1 mrg find_indirect_cycles (graph); 7453 1.1 mrg 7454 1.1 mrg /* Implicit nodes and predecessors are no longer necessary at this 7455 1.1 mrg point. */ 7456 1.1 mrg remove_preds_and_fake_succs (graph); 7457 1.1 mrg 7458 1.1 mrg if (dump_file && (dump_flags & TDF_GRAPH)) 7459 1.1 mrg { 7460 1.1 mrg fprintf (dump_file, "\n\n// The constraint graph before solve-graph " 7461 1.1 mrg "in dot format:\n"); 7462 1.1 mrg dump_constraint_graph (dump_file); 7463 1.1 mrg fprintf (dump_file, "\n\n"); 7464 1.1 mrg } 7465 1.1 mrg 7466 1.1 mrg if (dump_file) 7467 1.1 mrg fprintf (dump_file, "Solving graph\n"); 7468 1.1 mrg 7469 1.1 mrg solve_graph (graph); 7470 1.1 mrg 7471 1.1 mrg if (dump_file && (dump_flags & TDF_GRAPH)) 7472 1.1 mrg { 7473 1.1 mrg fprintf (dump_file, "\n\n// The constraint graph after solve-graph " 7474 1.1 mrg "in dot format:\n"); 7475 1.1 mrg dump_constraint_graph (dump_file); 7476 1.1 mrg fprintf (dump_file, "\n\n"); 7477 1.1 mrg } 7478 1.1 mrg } 7479 1.1 mrg 7480 1.1 mrg /* Create points-to sets for the current function. See the comments 7481 1.1 mrg at the start of the file for an algorithmic overview. */ 7482 1.1 mrg 7483 1.1 mrg static void 7484 1.1 mrg compute_points_to_sets (void) 7485 1.1 mrg { 7486 1.1 mrg basic_block bb; 7487 1.1 mrg varinfo_t vi; 7488 1.1 mrg 7489 1.1 mrg timevar_push (TV_TREE_PTA); 7490 1.1 mrg 7491 1.1 mrg init_alias_vars (); 7492 1.1 mrg 7493 1.1 mrg intra_create_variable_infos (cfun); 7494 1.1 mrg 7495 1.1 mrg /* Now walk all statements and build the constraint set. */ 7496 1.1 mrg FOR_EACH_BB_FN (bb, cfun) 7497 1.1 mrg { 7498 1.1 mrg for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi); 7499 1.1 mrg gsi_next (&gsi)) 7500 1.1 mrg { 7501 1.1 mrg gphi *phi = gsi.phi (); 7502 1.1 mrg 7503 1.1 mrg if (! virtual_operand_p (gimple_phi_result (phi))) 7504 1.1 mrg find_func_aliases (cfun, phi); 7505 1.1 mrg } 7506 1.1 mrg 7507 1.1 mrg for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); 7508 1.1 mrg gsi_next (&gsi)) 7509 1.1 mrg { 7510 1.1 mrg gimple *stmt = gsi_stmt (gsi); 7511 1.1 mrg 7512 1.1 mrg find_func_aliases (cfun, stmt); 7513 1.1 mrg } 7514 1.1 mrg } 7515 1.1 mrg 7516 1.1 mrg if (dump_file) 7517 1.1 mrg { 7518 1.1 mrg fprintf (dump_file, "Points-to analysis\n\nConstraints:\n\n"); 7519 1.1 mrg dump_constraints (dump_file, 0); 7520 1.1 mrg } 7521 1.1 mrg 7522 1.1 mrg /* From the constraints compute the points-to sets. */ 7523 1.1 mrg solve_constraints (); 7524 1.1 mrg 7525 1.1 mrg /* Post-process solutions for escapes through returns. */ 7526 1.1 mrg edge_iterator ei; 7527 1.1 mrg edge e; 7528 1.1 mrg FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) 7529 1.1 mrg if (greturn *ret = safe_dyn_cast <greturn *> (last_stmt (e->src))) 7530 1.1 mrg { 7531 1.1 mrg tree val = gimple_return_retval (ret); 7532 1.1 mrg /* ??? Easy to handle simple indirections with some work. 7533 1.1 mrg Arbitrary references like foo.bar.baz are more difficult 7534 1.1 mrg (but conservatively easy enough with just looking at the base). 7535 1.1 mrg Mind to fixup find_func_aliases as well. */ 7536 1.1 mrg if (!val || !SSA_VAR_P (val)) 7537 1.1 mrg continue; 7538 1.1 mrg /* returns happen last in non-IPA so they only influence 7539 1.1 mrg the ESCAPED solution and we can filter local variables. */ 7540 1.1 mrg varinfo_t escaped_vi = get_varinfo (find (escaped_id)); 7541 1.1 mrg varinfo_t vi = lookup_vi_for_tree (val); 7542 1.1 mrg bitmap delta = BITMAP_ALLOC (&pta_obstack); 7543 1.1 mrg bitmap_iterator bi; 7544 1.1 mrg unsigned i; 7545 1.1 mrg for (; vi; vi = vi_next (vi)) 7546 1.1 mrg { 7547 1.1 mrg varinfo_t part_vi = get_varinfo (find (vi->id)); 7548 1.1 mrg EXECUTE_IF_AND_COMPL_IN_BITMAP (part_vi->solution, 7549 1.1 mrg escaped_vi->solution, 0, i, bi) 7550 1.1 mrg { 7551 1.1 mrg varinfo_t pointed_to_vi = get_varinfo (i); 7552 1.1 mrg if (pointed_to_vi->is_global_var 7553 1.1 mrg /* We delay marking of heap memory as global. */ 7554 1.1 mrg || pointed_to_vi->is_heap_var) 7555 1.1 mrg bitmap_set_bit (delta, i); 7556 1.1 mrg } 7557 1.1 mrg } 7558 1.1 mrg 7559 1.1 mrg /* Now compute the transitive closure. */ 7560 1.1 mrg bitmap_ior_into (escaped_vi->solution, delta); 7561 1.1 mrg bitmap new_delta = BITMAP_ALLOC (&pta_obstack); 7562 1.1 mrg while (!bitmap_empty_p (delta)) 7563 1.1 mrg { 7564 1.1 mrg EXECUTE_IF_SET_IN_BITMAP (delta, 0, i, bi) 7565 1.1 mrg { 7566 1.1 mrg varinfo_t pointed_to_vi = get_varinfo (i); 7567 1.1 mrg pointed_to_vi = get_varinfo (find (pointed_to_vi->id)); 7568 1.1 mrg unsigned j; 7569 1.1 mrg bitmap_iterator bi2; 7570 1.1 mrg EXECUTE_IF_AND_COMPL_IN_BITMAP (pointed_to_vi->solution, 7571 1.1 mrg escaped_vi->solution, 7572 1.1 mrg 0, j, bi2) 7573 1.1 mrg { 7574 1.1 mrg varinfo_t pointed_to_vi2 = get_varinfo (j); 7575 1.1 mrg if (pointed_to_vi2->is_global_var 7576 1.1 mrg /* We delay marking of heap memory as global. */ 7577 1.1 mrg || pointed_to_vi2->is_heap_var) 7578 1.1 mrg bitmap_set_bit (new_delta, j); 7579 1.1 mrg } 7580 1.1 mrg } 7581 1.1 mrg bitmap_ior_into (escaped_vi->solution, new_delta); 7582 1.1 mrg bitmap_clear (delta); 7583 1.1 mrg std::swap (delta, new_delta); 7584 1.1 mrg } 7585 1.1 mrg BITMAP_FREE (delta); 7586 1.1 mrg BITMAP_FREE (new_delta); 7587 1.1 mrg } 7588 1.1 mrg 7589 1.1 mrg if (dump_file) 7590 1.1 mrg dump_sa_points_to_info (dump_file); 7591 1.1 mrg 7592 1.1 mrg /* Compute the points-to set for ESCAPED used for call-clobber analysis. */ 7593 1.1 mrg cfun->gimple_df->escaped = find_what_var_points_to (cfun->decl, 7594 1.1 mrg get_varinfo (escaped_id)); 7595 1.1 mrg 7596 1.1 mrg /* Make sure the ESCAPED solution (which is used as placeholder in 7597 1.1 mrg other solutions) does not reference itself. This simplifies 7598 1.1 mrg points-to solution queries. */ 7599 1.1 mrg cfun->gimple_df->escaped.escaped = 0; 7600 1.1 mrg 7601 1.1 mrg /* Compute the points-to sets for pointer SSA_NAMEs. */ 7602 1.1 mrg unsigned i; 7603 1.1 mrg tree ptr; 7604 1.1 mrg 7605 1.1 mrg FOR_EACH_SSA_NAME (i, ptr, cfun) 7606 1.1 mrg { 7607 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (ptr))) 7608 1.1 mrg find_what_p_points_to (cfun->decl, ptr); 7609 1.1 mrg } 7610 1.1 mrg 7611 1.1 mrg /* Compute the call-used/clobbered sets. */ 7612 1.1 mrg FOR_EACH_BB_FN (bb, cfun) 7613 1.1 mrg { 7614 1.1 mrg gimple_stmt_iterator gsi; 7615 1.1 mrg 7616 1.1 mrg for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) 7617 1.1 mrg { 7618 1.1 mrg gcall *stmt; 7619 1.1 mrg struct pt_solution *pt; 7620 1.1 mrg 7621 1.1 mrg stmt = dyn_cast <gcall *> (gsi_stmt (gsi)); 7622 1.1 mrg if (!stmt) 7623 1.1 mrg continue; 7624 1.1 mrg 7625 1.1 mrg pt = gimple_call_use_set (stmt); 7626 1.1 mrg if (gimple_call_flags (stmt) & ECF_CONST) 7627 1.1 mrg memset (pt, 0, sizeof (struct pt_solution)); 7628 1.1 mrg else 7629 1.1 mrg { 7630 1.1 mrg bool uses_global_memory = true; 7631 1.1 mrg bool reads_global_memory = true; 7632 1.1 mrg 7633 1.1 mrg determine_global_memory_access (stmt, NULL, 7634 1.1 mrg &reads_global_memory, 7635 1.1 mrg &uses_global_memory); 7636 1.1 mrg if ((vi = lookup_call_use_vi (stmt)) != NULL) 7637 1.1 mrg { 7638 1.1 mrg *pt = find_what_var_points_to (cfun->decl, vi); 7639 1.1 mrg /* Escaped (and thus nonlocal) variables are always 7640 1.1 mrg implicitly used by calls. */ 7641 1.1 mrg /* ??? ESCAPED can be empty even though NONLOCAL 7642 1.1 mrg always escaped. */ 7643 1.1 mrg if (uses_global_memory) 7644 1.1 mrg { 7645 1.1 mrg pt->nonlocal = 1; 7646 1.1 mrg pt->escaped = 1; 7647 1.1 mrg } 7648 1.1 mrg } 7649 1.1 mrg else if (uses_global_memory) 7650 1.1 mrg { 7651 1.1 mrg /* If there is nothing special about this call then 7652 1.1 mrg we have made everything that is used also escape. */ 7653 1.1 mrg *pt = cfun->gimple_df->escaped; 7654 1.1 mrg pt->nonlocal = 1; 7655 1.1 mrg } 7656 1.1 mrg else 7657 1.1 mrg memset (pt, 0, sizeof (struct pt_solution)); 7658 1.1 mrg } 7659 1.1 mrg 7660 1.1 mrg pt = gimple_call_clobber_set (stmt); 7661 1.1 mrg if (gimple_call_flags (stmt) & (ECF_CONST|ECF_PURE|ECF_NOVOPS)) 7662 1.1 mrg memset (pt, 0, sizeof (struct pt_solution)); 7663 1.1 mrg else 7664 1.1 mrg { 7665 1.1 mrg bool writes_global_memory = true; 7666 1.1 mrg 7667 1.1 mrg determine_global_memory_access (stmt, &writes_global_memory, 7668 1.1 mrg NULL, NULL); 7669 1.1 mrg 7670 1.1 mrg if ((vi = lookup_call_clobber_vi (stmt)) != NULL) 7671 1.1 mrg { 7672 1.1 mrg *pt = find_what_var_points_to (cfun->decl, vi); 7673 1.1 mrg /* Escaped (and thus nonlocal) variables are always 7674 1.1 mrg implicitly clobbered by calls. */ 7675 1.1 mrg /* ??? ESCAPED can be empty even though NONLOCAL 7676 1.1 mrg always escaped. */ 7677 1.1 mrg if (writes_global_memory) 7678 1.1 mrg { 7679 1.1 mrg pt->nonlocal = 1; 7680 1.1 mrg pt->escaped = 1; 7681 1.1 mrg } 7682 1.1 mrg } 7683 1.1 mrg else if (writes_global_memory) 7684 1.1 mrg { 7685 1.1 mrg /* If there is nothing special about this call then 7686 1.1 mrg we have made everything that is used also escape. */ 7687 1.1 mrg *pt = cfun->gimple_df->escaped; 7688 1.1 mrg pt->nonlocal = 1; 7689 1.1 mrg } 7690 1.1 mrg else 7691 1.1 mrg memset (pt, 0, sizeof (struct pt_solution)); 7692 1.1 mrg } 7693 1.1 mrg } 7694 1.1 mrg } 7695 1.1 mrg 7696 1.1 mrg timevar_pop (TV_TREE_PTA); 7697 1.1 mrg } 7698 1.1 mrg 7699 1.1 mrg 7700 1.1 mrg /* Delete created points-to sets. */ 7701 1.1 mrg 7702 1.1 mrg static void 7703 1.1 mrg delete_points_to_sets (void) 7704 1.1 mrg { 7705 1.1 mrg unsigned int i; 7706 1.1 mrg 7707 1.1 mrg delete shared_bitmap_table; 7708 1.1 mrg shared_bitmap_table = NULL; 7709 1.1 mrg if (dump_file && (dump_flags & TDF_STATS)) 7710 1.1 mrg fprintf (dump_file, "Points to sets created:%d\n", 7711 1.1 mrg stats.points_to_sets_created); 7712 1.1 mrg 7713 1.1 mrg delete vi_for_tree; 7714 1.1 mrg delete call_stmt_vars; 7715 1.1 mrg bitmap_obstack_release (&pta_obstack); 7716 1.1 mrg constraints.release (); 7717 1.1 mrg 7718 1.1 mrg for (i = 0; i < graph->size; i++) 7719 1.1 mrg graph->complex[i].release (); 7720 1.1 mrg free (graph->complex); 7721 1.1 mrg 7722 1.1 mrg free (graph->rep); 7723 1.1 mrg free (graph->succs); 7724 1.1 mrg free (graph->pe); 7725 1.1 mrg free (graph->pe_rep); 7726 1.1 mrg free (graph->indirect_cycles); 7727 1.1 mrg free (graph); 7728 1.1 mrg 7729 1.1 mrg varmap.release (); 7730 1.1 mrg variable_info_pool.release (); 7731 1.1 mrg constraint_pool.release (); 7732 1.1 mrg 7733 1.1 mrg obstack_free (&fake_var_decl_obstack, NULL); 7734 1.1 mrg 7735 1.1 mrg delete final_solutions; 7736 1.1 mrg obstack_free (&final_solutions_obstack, NULL); 7737 1.1 mrg } 7738 1.1 mrg 7739 1.1 mrg struct vls_data 7740 1.1 mrg { 7741 1.1 mrg unsigned short clique; 7742 1.1 mrg bool escaped_p; 7743 1.1 mrg bitmap rvars; 7744 1.1 mrg }; 7745 1.1 mrg 7746 1.1 mrg /* Mark "other" loads and stores as belonging to CLIQUE and with 7747 1.1 mrg base zero. */ 7748 1.1 mrg 7749 1.1 mrg static bool 7750 1.1 mrg visit_loadstore (gimple *, tree base, tree ref, void *data) 7751 1.1 mrg { 7752 1.1 mrg unsigned short clique = ((vls_data *) data)->clique; 7753 1.1 mrg bitmap rvars = ((vls_data *) data)->rvars; 7754 1.1 mrg bool escaped_p = ((vls_data *) data)->escaped_p; 7755 1.1 mrg if (TREE_CODE (base) == MEM_REF 7756 1.1 mrg || TREE_CODE (base) == TARGET_MEM_REF) 7757 1.1 mrg { 7758 1.1 mrg tree ptr = TREE_OPERAND (base, 0); 7759 1.1 mrg if (TREE_CODE (ptr) == SSA_NAME) 7760 1.1 mrg { 7761 1.1 mrg /* For parameters, get at the points-to set for the actual parm 7762 1.1 mrg decl. */ 7763 1.1 mrg if (SSA_NAME_IS_DEFAULT_DEF (ptr) 7764 1.1 mrg && (TREE_CODE (SSA_NAME_VAR (ptr)) == PARM_DECL 7765 1.1 mrg || TREE_CODE (SSA_NAME_VAR (ptr)) == RESULT_DECL)) 7766 1.1 mrg ptr = SSA_NAME_VAR (ptr); 7767 1.1 mrg 7768 1.1 mrg /* We need to make sure 'ptr' doesn't include any of 7769 1.1 mrg the restrict tags we added bases for in its points-to set. */ 7770 1.1 mrg varinfo_t vi = lookup_vi_for_tree (ptr); 7771 1.1 mrg if (! vi) 7772 1.1 mrg return false; 7773 1.1 mrg 7774 1.1 mrg vi = get_varinfo (find (vi->id)); 7775 1.1 mrg if (bitmap_intersect_p (rvars, vi->solution) 7776 1.1 mrg || (escaped_p && bitmap_bit_p (vi->solution, escaped_id))) 7777 1.1 mrg return false; 7778 1.1 mrg } 7779 1.1 mrg 7780 1.1 mrg /* Do not overwrite existing cliques (that includes clique, base 7781 1.1 mrg pairs we just set). */ 7782 1.1 mrg if (MR_DEPENDENCE_CLIQUE (base) == 0) 7783 1.1 mrg { 7784 1.1 mrg MR_DEPENDENCE_CLIQUE (base) = clique; 7785 1.1 mrg MR_DEPENDENCE_BASE (base) = 0; 7786 1.1 mrg } 7787 1.1 mrg } 7788 1.1 mrg 7789 1.1 mrg /* For plain decl accesses see whether they are accesses to globals 7790 1.1 mrg and rewrite them to MEM_REFs with { clique, 0 }. */ 7791 1.1 mrg if (VAR_P (base) 7792 1.1 mrg && is_global_var (base) 7793 1.1 mrg /* ??? We can't rewrite a plain decl with the walk_stmt_load_store 7794 1.1 mrg ops callback. */ 7795 1.1 mrg && base != ref) 7796 1.1 mrg { 7797 1.1 mrg tree *basep = &ref; 7798 1.1 mrg while (handled_component_p (*basep)) 7799 1.1 mrg basep = &TREE_OPERAND (*basep, 0); 7800 1.1 mrg gcc_assert (VAR_P (*basep)); 7801 1.1 mrg tree ptr = build_fold_addr_expr (*basep); 7802 1.1 mrg tree zero = build_int_cst (TREE_TYPE (ptr), 0); 7803 1.1 mrg *basep = build2 (MEM_REF, TREE_TYPE (*basep), ptr, zero); 7804 1.1 mrg MR_DEPENDENCE_CLIQUE (*basep) = clique; 7805 1.1 mrg MR_DEPENDENCE_BASE (*basep) = 0; 7806 1.1 mrg } 7807 1.1 mrg 7808 1.1 mrg return false; 7809 1.1 mrg } 7810 1.1 mrg 7811 1.1 mrg struct msdi_data { 7812 1.1 mrg tree ptr; 7813 1.1 mrg unsigned short *clique; 7814 1.1 mrg unsigned short *last_ruid; 7815 1.1 mrg varinfo_t restrict_var; 7816 1.1 mrg }; 7817 1.1 mrg 7818 1.1 mrg /* If BASE is a MEM_REF then assign a clique, base pair to it, updating 7819 1.1 mrg CLIQUE, *RESTRICT_VAR and LAST_RUID as passed via DATA. 7820 1.1 mrg Return whether dependence info was assigned to BASE. */ 7821 1.1 mrg 7822 1.1 mrg static bool 7823 1.1 mrg maybe_set_dependence_info (gimple *, tree base, tree, void *data) 7824 1.1 mrg { 7825 1.1 mrg tree ptr = ((msdi_data *)data)->ptr; 7826 1.1 mrg unsigned short &clique = *((msdi_data *)data)->clique; 7827 1.1 mrg unsigned short &last_ruid = *((msdi_data *)data)->last_ruid; 7828 1.1 mrg varinfo_t restrict_var = ((msdi_data *)data)->restrict_var; 7829 1.1 mrg if ((TREE_CODE (base) == MEM_REF 7830 1.1 mrg || TREE_CODE (base) == TARGET_MEM_REF) 7831 1.1 mrg && TREE_OPERAND (base, 0) == ptr) 7832 1.1 mrg { 7833 1.1 mrg /* Do not overwrite existing cliques. This avoids overwriting dependence 7834 1.1 mrg info inlined from a function with restrict parameters inlined 7835 1.1 mrg into a function with restrict parameters. This usually means we 7836 1.1 mrg prefer to be precise in innermost loops. */ 7837 1.1 mrg if (MR_DEPENDENCE_CLIQUE (base) == 0) 7838 1.1 mrg { 7839 1.1 mrg if (clique == 0) 7840 1.1 mrg { 7841 1.1 mrg if (cfun->last_clique == 0) 7842 1.1 mrg cfun->last_clique = 1; 7843 1.1 mrg clique = 1; 7844 1.1 mrg } 7845 1.1 mrg if (restrict_var->ruid == 0) 7846 1.1 mrg restrict_var->ruid = ++last_ruid; 7847 1.1 mrg MR_DEPENDENCE_CLIQUE (base) = clique; 7848 1.1 mrg MR_DEPENDENCE_BASE (base) = restrict_var->ruid; 7849 1.1 mrg return true; 7850 1.1 mrg } 7851 1.1 mrg } 7852 1.1 mrg return false; 7853 1.1 mrg } 7854 1.1 mrg 7855 1.1 mrg /* Clear dependence info for the clique DATA. */ 7856 1.1 mrg 7857 1.1 mrg static bool 7858 1.1 mrg clear_dependence_clique (gimple *, tree base, tree, void *data) 7859 1.1 mrg { 7860 1.1 mrg unsigned short clique = (uintptr_t)data; 7861 1.1 mrg if ((TREE_CODE (base) == MEM_REF 7862 1.1 mrg || TREE_CODE (base) == TARGET_MEM_REF) 7863 1.1 mrg && MR_DEPENDENCE_CLIQUE (base) == clique) 7864 1.1 mrg { 7865 1.1 mrg MR_DEPENDENCE_CLIQUE (base) = 0; 7866 1.1 mrg MR_DEPENDENCE_BASE (base) = 0; 7867 1.1 mrg } 7868 1.1 mrg 7869 1.1 mrg return false; 7870 1.1 mrg } 7871 1.1 mrg 7872 1.1 mrg /* Compute the set of independend memory references based on restrict 7873 1.1 mrg tags and their conservative propagation to the points-to sets. */ 7874 1.1 mrg 7875 1.1 mrg static void 7876 1.1 mrg compute_dependence_clique (void) 7877 1.1 mrg { 7878 1.1 mrg /* First clear the special "local" clique. */ 7879 1.1 mrg basic_block bb; 7880 1.1 mrg if (cfun->last_clique != 0) 7881 1.1 mrg FOR_EACH_BB_FN (bb, cfun) 7882 1.1 mrg for (gimple_stmt_iterator gsi = gsi_start_bb (bb); 7883 1.1 mrg !gsi_end_p (gsi); gsi_next (&gsi)) 7884 1.1 mrg { 7885 1.1 mrg gimple *stmt = gsi_stmt (gsi); 7886 1.1 mrg walk_stmt_load_store_ops (stmt, (void *)(uintptr_t) 1, 7887 1.1 mrg clear_dependence_clique, 7888 1.1 mrg clear_dependence_clique); 7889 1.1 mrg } 7890 1.1 mrg 7891 1.1 mrg unsigned short clique = 0; 7892 1.1 mrg unsigned short last_ruid = 0; 7893 1.1 mrg bitmap rvars = BITMAP_ALLOC (NULL); 7894 1.1 mrg bool escaped_p = false; 7895 1.1 mrg for (unsigned i = 0; i < num_ssa_names; ++i) 7896 1.1 mrg { 7897 1.1 mrg tree ptr = ssa_name (i); 7898 1.1 mrg if (!ptr || !POINTER_TYPE_P (TREE_TYPE (ptr))) 7899 1.1 mrg continue; 7900 1.1 mrg 7901 1.1 mrg /* Avoid all this when ptr is not dereferenced? */ 7902 1.1 mrg tree p = ptr; 7903 1.1 mrg if (SSA_NAME_IS_DEFAULT_DEF (ptr) 7904 1.1 mrg && (TREE_CODE (SSA_NAME_VAR (ptr)) == PARM_DECL 7905 1.1 mrg || TREE_CODE (SSA_NAME_VAR (ptr)) == RESULT_DECL)) 7906 1.1 mrg p = SSA_NAME_VAR (ptr); 7907 1.1 mrg varinfo_t vi = lookup_vi_for_tree (p); 7908 1.1 mrg if (!vi) 7909 1.1 mrg continue; 7910 1.1 mrg vi = get_varinfo (find (vi->id)); 7911 1.1 mrg bitmap_iterator bi; 7912 1.1 mrg unsigned j; 7913 1.1 mrg varinfo_t restrict_var = NULL; 7914 1.1 mrg EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, j, bi) 7915 1.1 mrg { 7916 1.1 mrg varinfo_t oi = get_varinfo (j); 7917 1.1 mrg if (oi->head != j) 7918 1.1 mrg oi = get_varinfo (oi->head); 7919 1.1 mrg if (oi->is_restrict_var) 7920 1.1 mrg { 7921 1.1 mrg if (restrict_var 7922 1.1 mrg && restrict_var != oi) 7923 1.1 mrg { 7924 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 7925 1.1 mrg { 7926 1.1 mrg fprintf (dump_file, "found restrict pointed-to " 7927 1.1 mrg "for "); 7928 1.1 mrg print_generic_expr (dump_file, ptr); 7929 1.1 mrg fprintf (dump_file, " but not exclusively\n"); 7930 1.1 mrg } 7931 1.1 mrg restrict_var = NULL; 7932 1.1 mrg break; 7933 1.1 mrg } 7934 1.1 mrg restrict_var = oi; 7935 1.1 mrg } 7936 1.1 mrg /* NULL is the only other valid points-to entry. */ 7937 1.1 mrg else if (oi->id != nothing_id) 7938 1.1 mrg { 7939 1.1 mrg restrict_var = NULL; 7940 1.1 mrg break; 7941 1.1 mrg } 7942 1.1 mrg } 7943 1.1 mrg /* Ok, found that ptr must(!) point to a single(!) restrict 7944 1.1 mrg variable. */ 7945 1.1 mrg /* ??? PTA isn't really a proper propagation engine to compute 7946 1.1 mrg this property. 7947 1.1 mrg ??? We could handle merging of two restricts by unifying them. */ 7948 1.1 mrg if (restrict_var) 7949 1.1 mrg { 7950 1.1 mrg /* Now look at possible dereferences of ptr. */ 7951 1.1 mrg imm_use_iterator ui; 7952 1.1 mrg gimple *use_stmt; 7953 1.1 mrg bool used = false; 7954 1.1 mrg msdi_data data = { ptr, &clique, &last_ruid, restrict_var }; 7955 1.1 mrg FOR_EACH_IMM_USE_STMT (use_stmt, ui, ptr) 7956 1.1 mrg used |= walk_stmt_load_store_ops (use_stmt, &data, 7957 1.1 mrg maybe_set_dependence_info, 7958 1.1 mrg maybe_set_dependence_info); 7959 1.1 mrg if (used) 7960 1.1 mrg { 7961 1.1 mrg /* Add all subvars to the set of restrict pointed-to set. */ 7962 1.1 mrg for (unsigned sv = restrict_var->head; sv != 0; 7963 1.1 mrg sv = get_varinfo (sv)->next) 7964 1.1 mrg bitmap_set_bit (rvars, sv); 7965 1.1 mrg varinfo_t escaped = get_varinfo (find (escaped_id)); 7966 1.1 mrg if (bitmap_bit_p (escaped->solution, restrict_var->id)) 7967 1.1 mrg escaped_p = true; 7968 1.1 mrg } 7969 1.1 mrg } 7970 1.1 mrg } 7971 1.1 mrg 7972 1.1 mrg if (clique != 0) 7973 1.1 mrg { 7974 1.1 mrg /* Assign the BASE id zero to all accesses not based on a restrict 7975 1.1 mrg pointer. That way they get disambiguated against restrict 7976 1.1 mrg accesses but not against each other. */ 7977 1.1 mrg /* ??? For restricts derived from globals (thus not incoming 7978 1.1 mrg parameters) we can't restrict scoping properly thus the following 7979 1.1 mrg is too aggressive there. For now we have excluded those globals from 7980 1.1 mrg getting into the MR_DEPENDENCE machinery. */ 7981 1.1 mrg vls_data data = { clique, escaped_p, rvars }; 7982 1.1 mrg basic_block bb; 7983 1.1 mrg FOR_EACH_BB_FN (bb, cfun) 7984 1.1 mrg for (gimple_stmt_iterator gsi = gsi_start_bb (bb); 7985 1.1 mrg !gsi_end_p (gsi); gsi_next (&gsi)) 7986 1.1 mrg { 7987 1.1 mrg gimple *stmt = gsi_stmt (gsi); 7988 1.1 mrg walk_stmt_load_store_ops (stmt, &data, 7989 1.1 mrg visit_loadstore, visit_loadstore); 7990 1.1 mrg } 7991 1.1 mrg } 7992 1.1 mrg 7993 1.1 mrg BITMAP_FREE (rvars); 7994 1.1 mrg } 7995 1.1 mrg 7996 1.1 mrg /* Compute points-to information for every SSA_NAME pointer in the 7997 1.1 mrg current function and compute the transitive closure of escaped 7998 1.1 mrg variables to re-initialize the call-clobber states of local variables. */ 7999 1.1 mrg 8000 1.1 mrg unsigned int 8001 1.1 mrg compute_may_aliases (void) 8002 1.1 mrg { 8003 1.1 mrg if (cfun->gimple_df->ipa_pta) 8004 1.1 mrg { 8005 1.1 mrg if (dump_file) 8006 1.1 mrg { 8007 1.1 mrg fprintf (dump_file, "\nNot re-computing points-to information " 8008 1.1 mrg "because IPA points-to information is available.\n\n"); 8009 1.1 mrg 8010 1.1 mrg /* But still dump what we have remaining it. */ 8011 1.1 mrg dump_alias_info (dump_file); 8012 1.1 mrg } 8013 1.1 mrg 8014 1.1 mrg return 0; 8015 1.1 mrg } 8016 1.1 mrg 8017 1.1 mrg /* For each pointer P_i, determine the sets of variables that P_i may 8018 1.1 mrg point-to. Compute the reachability set of escaped and call-used 8019 1.1 mrg variables. */ 8020 1.1 mrg compute_points_to_sets (); 8021 1.1 mrg 8022 1.1 mrg /* Debugging dumps. */ 8023 1.1 mrg if (dump_file) 8024 1.1 mrg dump_alias_info (dump_file); 8025 1.1 mrg 8026 1.1 mrg /* Compute restrict-based memory disambiguations. */ 8027 1.1 mrg compute_dependence_clique (); 8028 1.1 mrg 8029 1.1 mrg /* Deallocate memory used by aliasing data structures and the internal 8030 1.1 mrg points-to solution. */ 8031 1.1 mrg delete_points_to_sets (); 8032 1.1 mrg 8033 1.1 mrg gcc_assert (!need_ssa_update_p (cfun)); 8034 1.1 mrg 8035 1.1 mrg return 0; 8036 1.1 mrg } 8037 1.1 mrg 8038 1.1 mrg /* A dummy pass to cause points-to information to be computed via 8039 1.1 mrg TODO_rebuild_alias. */ 8040 1.1 mrg 8041 1.1 mrg namespace { 8042 1.1 mrg 8043 1.1 mrg const pass_data pass_data_build_alias = 8044 1.1 mrg { 8045 1.1 mrg GIMPLE_PASS, /* type */ 8046 1.1 mrg "alias", /* name */ 8047 1.1 mrg OPTGROUP_NONE, /* optinfo_flags */ 8048 1.1 mrg TV_NONE, /* tv_id */ 8049 1.1 mrg ( PROP_cfg | PROP_ssa ), /* properties_required */ 8050 1.1 mrg 0, /* properties_provided */ 8051 1.1 mrg 0, /* properties_destroyed */ 8052 1.1 mrg 0, /* todo_flags_start */ 8053 1.1 mrg TODO_rebuild_alias, /* todo_flags_finish */ 8054 1.1 mrg }; 8055 1.1 mrg 8056 1.1 mrg class pass_build_alias : public gimple_opt_pass 8057 1.1 mrg { 8058 1.1 mrg public: 8059 1.1 mrg pass_build_alias (gcc::context *ctxt) 8060 1.1 mrg : gimple_opt_pass (pass_data_build_alias, ctxt) 8061 1.1 mrg {} 8062 1.1 mrg 8063 1.1 mrg /* opt_pass methods: */ 8064 1.1 mrg virtual bool gate (function *) { return flag_tree_pta; } 8065 1.1 mrg 8066 1.1 mrg }; // class pass_build_alias 8067 1.1 mrg 8068 1.1 mrg } // anon namespace 8069 1.1 mrg 8070 1.1 mrg gimple_opt_pass * 8071 1.1 mrg make_pass_build_alias (gcc::context *ctxt) 8072 1.1 mrg { 8073 1.1 mrg return new pass_build_alias (ctxt); 8074 1.1 mrg } 8075 1.1 mrg 8076 1.1 mrg /* A dummy pass to cause points-to information to be computed via 8077 1.1 mrg TODO_rebuild_alias. */ 8078 1.1 mrg 8079 1.1 mrg namespace { 8080 1.1 mrg 8081 1.1 mrg const pass_data pass_data_build_ealias = 8082 1.1 mrg { 8083 1.1 mrg GIMPLE_PASS, /* type */ 8084 1.1 mrg "ealias", /* name */ 8085 1.1 mrg OPTGROUP_NONE, /* optinfo_flags */ 8086 1.1 mrg TV_NONE, /* tv_id */ 8087 1.1 mrg ( PROP_cfg | PROP_ssa ), /* properties_required */ 8088 1.1 mrg 0, /* properties_provided */ 8089 1.1 mrg 0, /* properties_destroyed */ 8090 1.1 mrg 0, /* todo_flags_start */ 8091 1.1 mrg TODO_rebuild_alias, /* todo_flags_finish */ 8092 1.1 mrg }; 8093 1.1 mrg 8094 1.1 mrg class pass_build_ealias : public gimple_opt_pass 8095 1.1 mrg { 8096 1.1 mrg public: 8097 1.1 mrg pass_build_ealias (gcc::context *ctxt) 8098 1.1 mrg : gimple_opt_pass (pass_data_build_ealias, ctxt) 8099 1.1 mrg {} 8100 1.1 mrg 8101 1.1 mrg /* opt_pass methods: */ 8102 1.1 mrg virtual bool gate (function *) { return flag_tree_pta; } 8103 1.1 mrg 8104 1.1 mrg }; // class pass_build_ealias 8105 1.1 mrg 8106 1.1 mrg } // anon namespace 8107 1.1 mrg 8108 1.1 mrg gimple_opt_pass * 8109 1.1 mrg make_pass_build_ealias (gcc::context *ctxt) 8110 1.1 mrg { 8111 1.1 mrg return new pass_build_ealias (ctxt); 8112 1.1 mrg } 8113 1.1 mrg 8114 1.1 mrg 8115 1.1 mrg /* IPA PTA solutions for ESCAPED. */ 8116 1.1 mrg struct pt_solution ipa_escaped_pt 8117 1.1 mrg = { true, false, false, false, false, 8118 1.1 mrg false, false, false, false, false, NULL }; 8119 1.1 mrg 8120 1.1 mrg /* Associate node with varinfo DATA. Worker for 8121 1.1 mrg cgraph_for_symbol_thunks_and_aliases. */ 8122 1.1 mrg static bool 8123 1.1 mrg associate_varinfo_to_alias (struct cgraph_node *node, void *data) 8124 1.1 mrg { 8125 1.1 mrg if ((node->alias 8126 1.1 mrg || (node->thunk 8127 1.1 mrg && ! node->inlined_to)) 8128 1.1 mrg && node->analyzed 8129 1.1 mrg && !node->ifunc_resolver) 8130 1.1 mrg insert_vi_for_tree (node->decl, (varinfo_t)data); 8131 1.1 mrg return false; 8132 1.1 mrg } 8133 1.1 mrg 8134 1.1 mrg /* Dump varinfo VI to FILE. */ 8135 1.1 mrg 8136 1.1 mrg static void 8137 1.1 mrg dump_varinfo (FILE *file, varinfo_t vi) 8138 1.1 mrg { 8139 1.1 mrg if (vi == NULL) 8140 1.1 mrg return; 8141 1.1 mrg 8142 1.1 mrg fprintf (file, "%u: %s\n", vi->id, vi->name); 8143 1.1 mrg 8144 1.1 mrg const char *sep = " "; 8145 1.1 mrg if (vi->is_artificial_var) 8146 1.1 mrg fprintf (file, "%sartificial", sep); 8147 1.1 mrg if (vi->is_special_var) 8148 1.1 mrg fprintf (file, "%sspecial", sep); 8149 1.1 mrg if (vi->is_unknown_size_var) 8150 1.1 mrg fprintf (file, "%sunknown-size", sep); 8151 1.1 mrg if (vi->is_full_var) 8152 1.1 mrg fprintf (file, "%sfull", sep); 8153 1.1 mrg if (vi->is_heap_var) 8154 1.1 mrg fprintf (file, "%sheap", sep); 8155 1.1 mrg if (vi->may_have_pointers) 8156 1.1 mrg fprintf (file, "%smay-have-pointers", sep); 8157 1.1 mrg if (vi->only_restrict_pointers) 8158 1.1 mrg fprintf (file, "%sonly-restrict-pointers", sep); 8159 1.1 mrg if (vi->is_restrict_var) 8160 1.1 mrg fprintf (file, "%sis-restrict-var", sep); 8161 1.1 mrg if (vi->is_global_var) 8162 1.1 mrg fprintf (file, "%sglobal", sep); 8163 1.1 mrg if (vi->is_ipa_escape_point) 8164 1.1 mrg fprintf (file, "%sipa-escape-point", sep); 8165 1.1 mrg if (vi->is_fn_info) 8166 1.1 mrg fprintf (file, "%sfn-info", sep); 8167 1.1 mrg if (vi->ruid) 8168 1.1 mrg fprintf (file, "%srestrict-uid:%u", sep, vi->ruid); 8169 1.1 mrg if (vi->next) 8170 1.1 mrg fprintf (file, "%snext:%u", sep, vi->next); 8171 1.1 mrg if (vi->head != vi->id) 8172 1.1 mrg fprintf (file, "%shead:%u", sep, vi->head); 8173 1.1 mrg if (vi->offset) 8174 1.1 mrg fprintf (file, "%soffset:" HOST_WIDE_INT_PRINT_DEC, sep, vi->offset); 8175 1.1 mrg if (vi->size != ~(unsigned HOST_WIDE_INT)0) 8176 1.1 mrg fprintf (file, "%ssize:" HOST_WIDE_INT_PRINT_DEC, sep, vi->size); 8177 1.1 mrg if (vi->fullsize != ~(unsigned HOST_WIDE_INT)0 8178 1.1 mrg && vi->fullsize != vi->size) 8179 1.1 mrg fprintf (file, "%sfullsize:" HOST_WIDE_INT_PRINT_DEC, sep, 8180 1.1 mrg vi->fullsize); 8181 1.1 mrg fprintf (file, "\n"); 8182 1.1 mrg 8183 1.1 mrg if (vi->solution && !bitmap_empty_p (vi->solution)) 8184 1.1 mrg { 8185 1.1 mrg bitmap_iterator bi; 8186 1.1 mrg unsigned i; 8187 1.1 mrg fprintf (file, " solution: {"); 8188 1.1 mrg EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi) 8189 1.1 mrg fprintf (file, " %u", i); 8190 1.1 mrg fprintf (file, " }\n"); 8191 1.1 mrg } 8192 1.1 mrg 8193 1.1 mrg if (vi->oldsolution && !bitmap_empty_p (vi->oldsolution) 8194 1.1 mrg && !bitmap_equal_p (vi->solution, vi->oldsolution)) 8195 1.1 mrg { 8196 1.1 mrg bitmap_iterator bi; 8197 1.1 mrg unsigned i; 8198 1.1 mrg fprintf (file, " oldsolution: {"); 8199 1.1 mrg EXECUTE_IF_SET_IN_BITMAP (vi->oldsolution, 0, i, bi) 8200 1.1 mrg fprintf (file, " %u", i); 8201 1.1 mrg fprintf (file, " }\n"); 8202 1.1 mrg } 8203 1.1 mrg } 8204 1.1 mrg 8205 1.1 mrg /* Dump varinfo VI to stderr. */ 8206 1.1 mrg 8207 1.1 mrg DEBUG_FUNCTION void 8208 1.1 mrg debug_varinfo (varinfo_t vi) 8209 1.1 mrg { 8210 1.1 mrg dump_varinfo (stderr, vi); 8211 1.1 mrg } 8212 1.1 mrg 8213 1.1 mrg /* Dump varmap to FILE. */ 8214 1.1 mrg 8215 1.1 mrg static void 8216 1.1 mrg dump_varmap (FILE *file) 8217 1.1 mrg { 8218 1.1 mrg if (varmap.length () == 0) 8219 1.1 mrg return; 8220 1.1 mrg 8221 1.1 mrg fprintf (file, "variables:\n"); 8222 1.1 mrg 8223 1.1 mrg for (unsigned int i = 0; i < varmap.length (); ++i) 8224 1.1 mrg { 8225 1.1 mrg varinfo_t vi = get_varinfo (i); 8226 1.1 mrg dump_varinfo (file, vi); 8227 1.1 mrg } 8228 1.1 mrg 8229 1.1 mrg fprintf (file, "\n"); 8230 1.1 mrg } 8231 1.1 mrg 8232 1.1 mrg /* Dump varmap to stderr. */ 8233 1.1 mrg 8234 1.1 mrg DEBUG_FUNCTION void 8235 1.1 mrg debug_varmap (void) 8236 1.1 mrg { 8237 1.1 mrg dump_varmap (stderr); 8238 1.1 mrg } 8239 1.1 mrg 8240 1.1 mrg /* Compute whether node is refered to non-locally. Worker for 8241 1.1 mrg cgraph_for_symbol_thunks_and_aliases. */ 8242 1.1 mrg static bool 8243 1.1 mrg refered_from_nonlocal_fn (struct cgraph_node *node, void *data) 8244 1.1 mrg { 8245 1.1 mrg bool *nonlocal_p = (bool *)data; 8246 1.1 mrg *nonlocal_p |= (node->used_from_other_partition 8247 1.1 mrg || DECL_EXTERNAL (node->decl) 8248 1.1 mrg || TREE_PUBLIC (node->decl) 8249 1.1 mrg || node->force_output 8250 1.1 mrg || lookup_attribute ("noipa", DECL_ATTRIBUTES (node->decl))); 8251 1.1 mrg return false; 8252 1.1 mrg } 8253 1.1 mrg 8254 1.1 mrg /* Same for varpool nodes. */ 8255 1.1 mrg static bool 8256 1.1 mrg refered_from_nonlocal_var (struct varpool_node *node, void *data) 8257 1.1 mrg { 8258 1.1 mrg bool *nonlocal_p = (bool *)data; 8259 1.1 mrg *nonlocal_p |= (node->used_from_other_partition 8260 1.1 mrg || DECL_EXTERNAL (node->decl) 8261 1.1 mrg || TREE_PUBLIC (node->decl) 8262 1.1 mrg || node->force_output); 8263 1.1 mrg return false; 8264 1.1 mrg } 8265 1.1 mrg 8266 1.1 mrg /* Execute the driver for IPA PTA. */ 8267 1.1 mrg static unsigned int 8268 1.1 mrg ipa_pta_execute (void) 8269 1.1 mrg { 8270 1.1 mrg struct cgraph_node *node; 8271 1.1 mrg varpool_node *var; 8272 1.1 mrg unsigned int from = 0; 8273 1.1 mrg 8274 1.1 mrg in_ipa_mode = 1; 8275 1.1 mrg 8276 1.1 mrg init_alias_vars (); 8277 1.1 mrg 8278 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 8279 1.1 mrg { 8280 1.1 mrg symtab->dump (dump_file); 8281 1.1 mrg fprintf (dump_file, "\n"); 8282 1.1 mrg } 8283 1.1 mrg 8284 1.1 mrg if (dump_file) 8285 1.1 mrg { 8286 1.1 mrg fprintf (dump_file, "Generating generic constraints\n\n"); 8287 1.1 mrg dump_constraints (dump_file, from); 8288 1.1 mrg fprintf (dump_file, "\n"); 8289 1.1 mrg from = constraints.length (); 8290 1.1 mrg } 8291 1.1 mrg 8292 1.1 mrg /* Build the constraints. */ 8293 1.1 mrg FOR_EACH_DEFINED_FUNCTION (node) 8294 1.1 mrg { 8295 1.1 mrg varinfo_t vi; 8296 1.1 mrg /* Nodes without a body in this partition are not interesting. 8297 1.1 mrg Especially do not visit clones at this point for now - we 8298 1.1 mrg get duplicate decls there for inline clones at least. */ 8299 1.1 mrg if (!node->has_gimple_body_p () 8300 1.1 mrg || node->in_other_partition 8301 1.1 mrg || node->inlined_to) 8302 1.1 mrg continue; 8303 1.1 mrg node->get_body (); 8304 1.1 mrg 8305 1.1 mrg gcc_assert (!node->clone_of); 8306 1.1 mrg 8307 1.1 mrg /* For externally visible or attribute used annotated functions use 8308 1.1 mrg local constraints for their arguments. 8309 1.1 mrg For local functions we see all callers and thus do not need initial 8310 1.1 mrg constraints for parameters. */ 8311 1.1 mrg bool nonlocal_p = (node->used_from_other_partition 8312 1.1 mrg || DECL_EXTERNAL (node->decl) 8313 1.1 mrg || TREE_PUBLIC (node->decl) 8314 1.1 mrg || node->force_output 8315 1.1 mrg || lookup_attribute ("noipa", 8316 1.1 mrg DECL_ATTRIBUTES (node->decl))); 8317 1.1 mrg node->call_for_symbol_thunks_and_aliases (refered_from_nonlocal_fn, 8318 1.1 mrg &nonlocal_p, true); 8319 1.1 mrg 8320 1.1 mrg vi = create_function_info_for (node->decl, 8321 1.1 mrg alias_get_name (node->decl), false, 8322 1.1 mrg nonlocal_p); 8323 1.1 mrg if (dump_file 8324 1.1 mrg && from != constraints.length ()) 8325 1.1 mrg { 8326 1.1 mrg fprintf (dump_file, 8327 1.1 mrg "Generating initial constraints for %s", 8328 1.1 mrg node->dump_name ()); 8329 1.1 mrg if (DECL_ASSEMBLER_NAME_SET_P (node->decl)) 8330 1.1 mrg fprintf (dump_file, " (%s)", 8331 1.1 mrg IDENTIFIER_POINTER 8332 1.1 mrg (DECL_ASSEMBLER_NAME (node->decl))); 8333 1.1 mrg fprintf (dump_file, "\n\n"); 8334 1.1 mrg dump_constraints (dump_file, from); 8335 1.1 mrg fprintf (dump_file, "\n"); 8336 1.1 mrg 8337 1.1 mrg from = constraints.length (); 8338 1.1 mrg } 8339 1.1 mrg 8340 1.1 mrg node->call_for_symbol_thunks_and_aliases 8341 1.1 mrg (associate_varinfo_to_alias, vi, true); 8342 1.1 mrg } 8343 1.1 mrg 8344 1.1 mrg /* Create constraints for global variables and their initializers. */ 8345 1.1 mrg FOR_EACH_VARIABLE (var) 8346 1.1 mrg { 8347 1.1 mrg if (var->alias && var->analyzed) 8348 1.1 mrg continue; 8349 1.1 mrg 8350 1.1 mrg varinfo_t vi = get_vi_for_tree (var->decl); 8351 1.1 mrg 8352 1.1 mrg /* For the purpose of IPA PTA unit-local globals are not 8353 1.1 mrg escape points. */ 8354 1.1 mrg bool nonlocal_p = (DECL_EXTERNAL (var->decl) 8355 1.1 mrg || TREE_PUBLIC (var->decl) 8356 1.1 mrg || var->used_from_other_partition 8357 1.1 mrg || var->force_output); 8358 1.1 mrg var->call_for_symbol_and_aliases (refered_from_nonlocal_var, 8359 1.1 mrg &nonlocal_p, true); 8360 1.1 mrg if (nonlocal_p) 8361 1.1 mrg vi->is_ipa_escape_point = true; 8362 1.1 mrg } 8363 1.1 mrg 8364 1.1 mrg if (dump_file 8365 1.1 mrg && from != constraints.length ()) 8366 1.1 mrg { 8367 1.1 mrg fprintf (dump_file, 8368 1.1 mrg "Generating constraints for global initializers\n\n"); 8369 1.1 mrg dump_constraints (dump_file, from); 8370 1.1 mrg fprintf (dump_file, "\n"); 8371 1.1 mrg from = constraints.length (); 8372 1.1 mrg } 8373 1.1 mrg 8374 1.1 mrg FOR_EACH_DEFINED_FUNCTION (node) 8375 1.1 mrg { 8376 1.1 mrg struct function *func; 8377 1.1 mrg basic_block bb; 8378 1.1 mrg 8379 1.1 mrg /* Nodes without a body in this partition are not interesting. */ 8380 1.1 mrg if (!node->has_gimple_body_p () 8381 1.1 mrg || node->in_other_partition 8382 1.1 mrg || node->clone_of) 8383 1.1 mrg continue; 8384 1.1 mrg 8385 1.1 mrg if (dump_file) 8386 1.1 mrg { 8387 1.1 mrg fprintf (dump_file, 8388 1.1 mrg "Generating constraints for %s", node->dump_name ()); 8389 1.1 mrg if (DECL_ASSEMBLER_NAME_SET_P (node->decl)) 8390 1.1 mrg fprintf (dump_file, " (%s)", 8391 1.1 mrg IDENTIFIER_POINTER 8392 1.1 mrg (DECL_ASSEMBLER_NAME (node->decl))); 8393 1.1 mrg fprintf (dump_file, "\n"); 8394 1.1 mrg } 8395 1.1 mrg 8396 1.1 mrg func = DECL_STRUCT_FUNCTION (node->decl); 8397 1.1 mrg gcc_assert (cfun == NULL); 8398 1.1 mrg 8399 1.1 mrg /* Build constriants for the function body. */ 8400 1.1 mrg FOR_EACH_BB_FN (bb, func) 8401 1.1 mrg { 8402 1.1 mrg for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi); 8403 1.1 mrg gsi_next (&gsi)) 8404 1.1 mrg { 8405 1.1 mrg gphi *phi = gsi.phi (); 8406 1.1 mrg 8407 1.1 mrg if (! virtual_operand_p (gimple_phi_result (phi))) 8408 1.1 mrg find_func_aliases (func, phi); 8409 1.1 mrg } 8410 1.1 mrg 8411 1.1 mrg for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); 8412 1.1 mrg gsi_next (&gsi)) 8413 1.1 mrg { 8414 1.1 mrg gimple *stmt = gsi_stmt (gsi); 8415 1.1 mrg 8416 1.1 mrg find_func_aliases (func, stmt); 8417 1.1 mrg find_func_clobbers (func, stmt); 8418 1.1 mrg } 8419 1.1 mrg } 8420 1.1 mrg 8421 1.1 mrg if (dump_file) 8422 1.1 mrg { 8423 1.1 mrg fprintf (dump_file, "\n"); 8424 1.1 mrg dump_constraints (dump_file, from); 8425 1.1 mrg fprintf (dump_file, "\n"); 8426 1.1 mrg from = constraints.length (); 8427 1.1 mrg } 8428 1.1 mrg } 8429 1.1 mrg 8430 1.1 mrg /* From the constraints compute the points-to sets. */ 8431 1.1 mrg solve_constraints (); 8432 1.1 mrg 8433 1.1 mrg if (dump_file) 8434 1.1 mrg dump_sa_points_to_info (dump_file); 8435 1.1 mrg 8436 1.1 mrg /* Now post-process solutions to handle locals from different 8437 1.1 mrg runtime instantiations coming in through recursive invocations. */ 8438 1.1 mrg unsigned shadow_var_cnt = 0; 8439 1.1 mrg for (unsigned i = 1; i < varmap.length (); ++i) 8440 1.1 mrg { 8441 1.1 mrg varinfo_t fi = get_varinfo (i); 8442 1.1 mrg if (fi->is_fn_info 8443 1.1 mrg && fi->decl) 8444 1.1 mrg /* Automatic variables pointed to by their containing functions 8445 1.1 mrg parameters need this treatment. */ 8446 1.1 mrg for (varinfo_t ai = first_vi_for_offset (fi, fi_parm_base); 8447 1.1 mrg ai; ai = vi_next (ai)) 8448 1.1 mrg { 8449 1.1 mrg varinfo_t vi = get_varinfo (find (ai->id)); 8450 1.1 mrg bitmap_iterator bi; 8451 1.1 mrg unsigned j; 8452 1.1 mrg EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, j, bi) 8453 1.1 mrg { 8454 1.1 mrg varinfo_t pt = get_varinfo (j); 8455 1.1 mrg if (pt->shadow_var_uid == 0 8456 1.1 mrg && pt->decl 8457 1.1 mrg && auto_var_in_fn_p (pt->decl, fi->decl)) 8458 1.1 mrg { 8459 1.1 mrg pt->shadow_var_uid = allocate_decl_uid (); 8460 1.1 mrg shadow_var_cnt++; 8461 1.1 mrg } 8462 1.1 mrg } 8463 1.1 mrg } 8464 1.1 mrg /* As well as global variables which are another way of passing 8465 1.1 mrg arguments to recursive invocations. */ 8466 1.1 mrg else if (fi->is_global_var) 8467 1.1 mrg { 8468 1.1 mrg for (varinfo_t ai = fi; ai; ai = vi_next (ai)) 8469 1.1 mrg { 8470 1.1 mrg varinfo_t vi = get_varinfo (find (ai->id)); 8471 1.1 mrg bitmap_iterator bi; 8472 1.1 mrg unsigned j; 8473 1.1 mrg EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, j, bi) 8474 1.1 mrg { 8475 1.1 mrg varinfo_t pt = get_varinfo (j); 8476 1.1 mrg if (pt->shadow_var_uid == 0 8477 1.1 mrg && pt->decl 8478 1.1 mrg && auto_var_p (pt->decl)) 8479 1.1 mrg { 8480 1.1 mrg pt->shadow_var_uid = allocate_decl_uid (); 8481 1.1 mrg shadow_var_cnt++; 8482 1.1 mrg } 8483 1.1 mrg } 8484 1.1 mrg } 8485 1.1 mrg } 8486 1.1 mrg } 8487 1.1 mrg if (shadow_var_cnt && dump_file && (dump_flags & TDF_DETAILS)) 8488 1.1 mrg fprintf (dump_file, "Allocated %u shadow variables for locals " 8489 1.1 mrg "maybe leaking into recursive invocations of their containing " 8490 1.1 mrg "functions\n", shadow_var_cnt); 8491 1.1 mrg 8492 1.1 mrg /* Compute the global points-to sets for ESCAPED. 8493 1.1 mrg ??? Note that the computed escape set is not correct 8494 1.1 mrg for the whole unit as we fail to consider graph edges to 8495 1.1 mrg externally visible functions. */ 8496 1.1 mrg ipa_escaped_pt = find_what_var_points_to (NULL, get_varinfo (escaped_id)); 8497 1.1 mrg 8498 1.1 mrg /* Make sure the ESCAPED solution (which is used as placeholder in 8499 1.1 mrg other solutions) does not reference itself. This simplifies 8500 1.1 mrg points-to solution queries. */ 8501 1.1 mrg ipa_escaped_pt.ipa_escaped = 0; 8502 1.1 mrg 8503 1.1 mrg /* Assign the points-to sets to the SSA names in the unit. */ 8504 1.1 mrg FOR_EACH_DEFINED_FUNCTION (node) 8505 1.1 mrg { 8506 1.1 mrg tree ptr; 8507 1.1 mrg struct function *fn; 8508 1.1 mrg unsigned i; 8509 1.1 mrg basic_block bb; 8510 1.1 mrg 8511 1.1 mrg /* Nodes without a body in this partition are not interesting. */ 8512 1.1 mrg if (!node->has_gimple_body_p () 8513 1.1 mrg || node->in_other_partition 8514 1.1 mrg || node->clone_of) 8515 1.1 mrg continue; 8516 1.1 mrg 8517 1.1 mrg fn = DECL_STRUCT_FUNCTION (node->decl); 8518 1.1 mrg 8519 1.1 mrg /* Compute the points-to sets for pointer SSA_NAMEs. */ 8520 1.1 mrg FOR_EACH_VEC_ELT (*fn->gimple_df->ssa_names, i, ptr) 8521 1.1 mrg { 8522 1.1 mrg if (ptr 8523 1.1 mrg && POINTER_TYPE_P (TREE_TYPE (ptr))) 8524 1.1 mrg find_what_p_points_to (node->decl, ptr); 8525 1.1 mrg } 8526 1.1 mrg 8527 1.1 mrg /* Compute the call-use and call-clobber sets for indirect calls 8528 1.1 mrg and calls to external functions. */ 8529 1.1 mrg FOR_EACH_BB_FN (bb, fn) 8530 1.1 mrg { 8531 1.1 mrg gimple_stmt_iterator gsi; 8532 1.1 mrg 8533 1.1 mrg for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) 8534 1.1 mrg { 8535 1.1 mrg gcall *stmt; 8536 1.1 mrg struct pt_solution *pt; 8537 1.1 mrg varinfo_t vi, fi; 8538 1.1 mrg tree decl; 8539 1.1 mrg 8540 1.1 mrg stmt = dyn_cast <gcall *> (gsi_stmt (gsi)); 8541 1.1 mrg if (!stmt) 8542 1.1 mrg continue; 8543 1.1 mrg 8544 1.1 mrg /* Handle direct calls to functions with body. */ 8545 1.1 mrg decl = gimple_call_fndecl (stmt); 8546 1.1 mrg 8547 1.1 mrg { 8548 1.1 mrg tree called_decl = NULL_TREE; 8549 1.1 mrg if (gimple_call_builtin_p (stmt, BUILT_IN_GOMP_PARALLEL)) 8550 1.1 mrg called_decl = TREE_OPERAND (gimple_call_arg (stmt, 0), 0); 8551 1.1 mrg else if (gimple_call_builtin_p (stmt, BUILT_IN_GOACC_PARALLEL)) 8552 1.1 mrg called_decl = TREE_OPERAND (gimple_call_arg (stmt, 1), 0); 8553 1.1 mrg 8554 1.1 mrg if (called_decl != NULL_TREE 8555 1.1 mrg && !fndecl_maybe_in_other_partition (called_decl)) 8556 1.1 mrg decl = called_decl; 8557 1.1 mrg } 8558 1.1 mrg 8559 1.1 mrg if (decl 8560 1.1 mrg && (fi = lookup_vi_for_tree (decl)) 8561 1.1 mrg && fi->is_fn_info) 8562 1.1 mrg { 8563 1.1 mrg *gimple_call_clobber_set (stmt) 8564 1.1 mrg = find_what_var_points_to 8565 1.1 mrg (node->decl, first_vi_for_offset (fi, fi_clobbers)); 8566 1.1 mrg *gimple_call_use_set (stmt) 8567 1.1 mrg = find_what_var_points_to 8568 1.1 mrg (node->decl, first_vi_for_offset (fi, fi_uses)); 8569 1.1 mrg } 8570 1.1 mrg /* Handle direct calls to external functions. */ 8571 1.1 mrg else if (decl && (!fi || fi->decl)) 8572 1.1 mrg { 8573 1.1 mrg pt = gimple_call_use_set (stmt); 8574 1.1 mrg if (gimple_call_flags (stmt) & ECF_CONST) 8575 1.1 mrg memset (pt, 0, sizeof (struct pt_solution)); 8576 1.1 mrg else if ((vi = lookup_call_use_vi (stmt)) != NULL) 8577 1.1 mrg { 8578 1.1 mrg *pt = find_what_var_points_to (node->decl, vi); 8579 1.1 mrg /* Escaped (and thus nonlocal) variables are always 8580 1.1 mrg implicitly used by calls. */ 8581 1.1 mrg /* ??? ESCAPED can be empty even though NONLOCAL 8582 1.1 mrg always escaped. */ 8583 1.1 mrg pt->nonlocal = 1; 8584 1.1 mrg pt->ipa_escaped = 1; 8585 1.1 mrg } 8586 1.1 mrg else 8587 1.1 mrg { 8588 1.1 mrg /* If there is nothing special about this call then 8589 1.1 mrg we have made everything that is used also escape. */ 8590 1.1 mrg *pt = ipa_escaped_pt; 8591 1.1 mrg pt->nonlocal = 1; 8592 1.1 mrg } 8593 1.1 mrg 8594 1.1 mrg pt = gimple_call_clobber_set (stmt); 8595 1.1 mrg if (gimple_call_flags (stmt) & (ECF_CONST|ECF_PURE|ECF_NOVOPS)) 8596 1.1 mrg memset (pt, 0, sizeof (struct pt_solution)); 8597 1.1 mrg else if ((vi = lookup_call_clobber_vi (stmt)) != NULL) 8598 1.1 mrg { 8599 1.1 mrg *pt = find_what_var_points_to (node->decl, vi); 8600 1.1 mrg /* Escaped (and thus nonlocal) variables are always 8601 1.1 mrg implicitly clobbered by calls. */ 8602 1.1 mrg /* ??? ESCAPED can be empty even though NONLOCAL 8603 1.1 mrg always escaped. */ 8604 1.1 mrg pt->nonlocal = 1; 8605 1.1 mrg pt->ipa_escaped = 1; 8606 1.1 mrg } 8607 1.1 mrg else 8608 1.1 mrg { 8609 1.1 mrg /* If there is nothing special about this call then 8610 1.1 mrg we have made everything that is used also escape. */ 8611 1.1 mrg *pt = ipa_escaped_pt; 8612 1.1 mrg pt->nonlocal = 1; 8613 1.1 mrg } 8614 1.1 mrg } 8615 1.1 mrg /* Handle indirect calls. */ 8616 1.1 mrg else if ((fi = get_fi_for_callee (stmt))) 8617 1.1 mrg { 8618 1.1 mrg /* We need to accumulate all clobbers/uses of all possible 8619 1.1 mrg callees. */ 8620 1.1 mrg fi = get_varinfo (find (fi->id)); 8621 1.1 mrg /* If we cannot constrain the set of functions we'll end up 8622 1.1 mrg calling we end up using/clobbering everything. */ 8623 1.1 mrg if (bitmap_bit_p (fi->solution, anything_id) 8624 1.1 mrg || bitmap_bit_p (fi->solution, nonlocal_id) 8625 1.1 mrg || bitmap_bit_p (fi->solution, escaped_id)) 8626 1.1 mrg { 8627 1.1 mrg pt_solution_reset (gimple_call_clobber_set (stmt)); 8628 1.1 mrg pt_solution_reset (gimple_call_use_set (stmt)); 8629 1.1 mrg } 8630 1.1 mrg else 8631 1.1 mrg { 8632 1.1 mrg bitmap_iterator bi; 8633 1.1 mrg unsigned i; 8634 1.1 mrg struct pt_solution *uses, *clobbers; 8635 1.1 mrg 8636 1.1 mrg uses = gimple_call_use_set (stmt); 8637 1.1 mrg clobbers = gimple_call_clobber_set (stmt); 8638 1.1 mrg memset (uses, 0, sizeof (struct pt_solution)); 8639 1.1 mrg memset (clobbers, 0, sizeof (struct pt_solution)); 8640 1.1 mrg EXECUTE_IF_SET_IN_BITMAP (fi->solution, 0, i, bi) 8641 1.1 mrg { 8642 1.1 mrg struct pt_solution sol; 8643 1.1 mrg 8644 1.1 mrg vi = get_varinfo (i); 8645 1.1 mrg if (!vi->is_fn_info) 8646 1.1 mrg { 8647 1.1 mrg /* ??? We could be more precise here? */ 8648 1.1 mrg uses->nonlocal = 1; 8649 1.1 mrg uses->ipa_escaped = 1; 8650 1.1 mrg clobbers->nonlocal = 1; 8651 1.1 mrg clobbers->ipa_escaped = 1; 8652 1.1 mrg continue; 8653 1.1 mrg } 8654 1.1 mrg 8655 1.1 mrg if (!uses->anything) 8656 1.1 mrg { 8657 1.1 mrg sol = find_what_var_points_to 8658 1.1 mrg (node->decl, 8659 1.1 mrg first_vi_for_offset (vi, fi_uses)); 8660 1.1 mrg pt_solution_ior_into (uses, &sol); 8661 1.1 mrg } 8662 1.1 mrg if (!clobbers->anything) 8663 1.1 mrg { 8664 1.1 mrg sol = find_what_var_points_to 8665 1.1 mrg (node->decl, 8666 1.1 mrg first_vi_for_offset (vi, fi_clobbers)); 8667 1.1 mrg pt_solution_ior_into (clobbers, &sol); 8668 1.1 mrg } 8669 1.1 mrg } 8670 1.1 mrg } 8671 1.1 mrg } 8672 1.1 mrg else 8673 1.1 mrg gcc_unreachable (); 8674 1.1 mrg } 8675 1.1 mrg } 8676 1.1 mrg 8677 1.1 mrg fn->gimple_df->ipa_pta = true; 8678 1.1 mrg 8679 1.1 mrg /* We have to re-set the final-solution cache after each function 8680 1.1 mrg because what is a "global" is dependent on function context. */ 8681 1.1 mrg final_solutions->empty (); 8682 1.1 mrg obstack_free (&final_solutions_obstack, NULL); 8683 1.1 mrg gcc_obstack_init (&final_solutions_obstack); 8684 1.1 mrg } 8685 1.1 mrg 8686 1.1 mrg delete_points_to_sets (); 8687 1.1 mrg 8688 1.1 mrg in_ipa_mode = 0; 8689 1.1 mrg 8690 1.1 mrg return 0; 8691 1.1 mrg } 8692 1.1 mrg 8693 1.1 mrg namespace { 8694 1.1 mrg 8695 1.1 mrg const pass_data pass_data_ipa_pta = 8696 1.1 mrg { 8697 1.1 mrg SIMPLE_IPA_PASS, /* type */ 8698 1.1 mrg "pta", /* name */ 8699 1.1 mrg OPTGROUP_NONE, /* optinfo_flags */ 8700 1.1 mrg TV_IPA_PTA, /* tv_id */ 8701 1.1 mrg 0, /* properties_required */ 8702 1.1 mrg 0, /* properties_provided */ 8703 1.1 mrg 0, /* properties_destroyed */ 8704 1.1 mrg 0, /* todo_flags_start */ 8705 1.1 mrg 0, /* todo_flags_finish */ 8706 1.1 mrg }; 8707 1.1 mrg 8708 1.1 mrg class pass_ipa_pta : public simple_ipa_opt_pass 8709 1.1 mrg { 8710 1.1 mrg public: 8711 1.1 mrg pass_ipa_pta (gcc::context *ctxt) 8712 1.1 mrg : simple_ipa_opt_pass (pass_data_ipa_pta, ctxt) 8713 1.1 mrg {} 8714 1.1 mrg 8715 1.1 mrg /* opt_pass methods: */ 8716 1.1 mrg virtual bool gate (function *) 8717 1.1 mrg { 8718 1.1 mrg return (optimize 8719 1.1 mrg && flag_ipa_pta 8720 1.1 mrg /* Don't bother doing anything if the program has errors. */ 8721 1.1 mrg && !seen_error ()); 8722 1.1 mrg } 8723 1.1 mrg 8724 1.1 mrg opt_pass * clone () { return new pass_ipa_pta (m_ctxt); } 8725 1.1 mrg 8726 1.1 mrg virtual unsigned int execute (function *) { return ipa_pta_execute (); } 8727 1.1 mrg 8728 1.1 mrg }; // class pass_ipa_pta 8729 1.1 mrg 8730 1.1 mrg } // anon namespace 8731 1.1 mrg 8732 1.1 mrg simple_ipa_opt_pass * 8733 1.1 mrg make_pass_ipa_pta (gcc::context *ctxt) 8734 1.1 mrg { 8735 1.1 mrg return new pass_ipa_pta (ctxt); 8736 1.1 mrg } 8737