Mercurial > hg > CbC > CbC_gcc
comparison gcc/ipa-type-escape.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | a06113de4d67 |
children | b7f97abdc517 |
comparison
equal
deleted
inserted
replaced
52:c156f1bd5cd9 | 55:77e2b8dfacca |
---|---|
41 #include "tree-flow.h" | 41 #include "tree-flow.h" |
42 #include "tree-inline.h" | 42 #include "tree-inline.h" |
43 #include "tree-pass.h" | 43 #include "tree-pass.h" |
44 #include "langhooks.h" | 44 #include "langhooks.h" |
45 #include "pointer-set.h" | 45 #include "pointer-set.h" |
46 #include "splay-tree.h" | |
46 #include "ggc.h" | 47 #include "ggc.h" |
47 #include "ipa-utils.h" | 48 #include "ipa-utils.h" |
48 #include "ipa-type-escape.h" | 49 #include "ipa-type-escape.h" |
49 #include "c-common.h" | |
50 #include "gimple.h" | 50 #include "gimple.h" |
51 #include "cgraph.h" | 51 #include "cgraph.h" |
52 #include "output.h" | 52 #include "output.h" |
53 #include "flags.h" | 53 #include "flags.h" |
54 #include "timevar.h" | 54 #include "timevar.h" |
88 | 88 |
89 /* The following two bit vectors global_types_* correspond to | 89 /* The following two bit vectors global_types_* correspond to |
90 previous cases above. During the analysis phase, a bit is set in | 90 previous cases above. During the analysis phase, a bit is set in |
91 one of these vectors if an operation of the offending class is | 91 one of these vectors if an operation of the offending class is |
92 discovered to happen on the associated type. */ | 92 discovered to happen on the associated type. */ |
93 | 93 |
94 static bitmap global_types_exposed_parameter; | 94 static bitmap global_types_exposed_parameter; |
95 static bitmap global_types_full_escape; | 95 static bitmap global_types_full_escape; |
96 | 96 |
97 /* All of the types seen in this compilation unit. */ | 97 /* All of the types seen in this compilation unit. */ |
98 static bitmap global_types_seen; | 98 static bitmap global_types_seen; |
132 recursively. */ | 132 recursively. */ |
133 static struct pointer_set_t *visited_stmts; | 133 static struct pointer_set_t *visited_stmts; |
134 | 134 |
135 static bitmap_obstack ipa_obstack; | 135 static bitmap_obstack ipa_obstack; |
136 | 136 |
137 /* Static functions from this file that are used | 137 /* Static functions from this file that are used |
138 before being defined. */ | 138 before being defined. */ |
139 static unsigned int look_for_casts (tree); | 139 static unsigned int look_for_casts (tree); |
140 static bool is_cast_from_non_pointer (tree, gimple, void *); | 140 static bool is_cast_from_non_pointer (tree, gimple, void *); |
141 | 141 |
142 /* Get the name of TYPE or return the string "<UNNAMED>". */ | 142 /* Get the name of TYPE or return the string "<UNNAMED>". */ |
143 static const char* | 143 static const char* |
144 get_name_of_type (tree type) | 144 get_name_of_type (tree type) |
145 { | 145 { |
146 tree name = TYPE_NAME (type); | 146 tree name = TYPE_NAME (type); |
147 | 147 |
148 if (!name) | 148 if (!name) |
149 /* Unnamed type, do what you like here. */ | 149 /* Unnamed type, do what you like here. */ |
150 return "<UNNAMED>"; | 150 return "<UNNAMED>"; |
151 | 151 |
152 /* It will be a TYPE_DECL in the case of a typedef, otherwise, an | 152 /* It will be a TYPE_DECL in the case of a typedef, otherwise, an |
153 identifier_node */ | 153 identifier_node */ |
154 if (TREE_CODE (name) == TYPE_DECL) | 154 if (TREE_CODE (name) == TYPE_DECL) |
155 { | 155 { |
156 /* Each DECL has a DECL_NAME field which contains an | 156 /* Each DECL has a DECL_NAME field which contains an |
162 /* Unnamed type, do what you like here. */ | 162 /* Unnamed type, do what you like here. */ |
163 return "<UNNAMED>"; | 163 return "<UNNAMED>"; |
164 } | 164 } |
165 else if (TREE_CODE (name) == IDENTIFIER_NODE) | 165 else if (TREE_CODE (name) == IDENTIFIER_NODE) |
166 return IDENTIFIER_POINTER (name); | 166 return IDENTIFIER_POINTER (name); |
167 else | 167 else |
168 return "<UNNAMED>"; | 168 return "<UNNAMED>"; |
169 } | 169 } |
170 | 170 |
171 struct type_brand_s | 171 struct type_brand_s |
172 { | 172 { |
173 const char* name; | 173 const char* name; |
174 int seq; | 174 int seq; |
175 }; | 175 }; |
176 | 176 |
177 /* Splay tree comparison function on type_brand_s structures. */ | 177 /* Splay tree comparison function on type_brand_s structures. */ |
178 | 178 |
179 static int | 179 static int |
180 compare_type_brand (splay_tree_key sk1, splay_tree_key sk2) | 180 compare_type_brand (splay_tree_key sk1, splay_tree_key sk2) |
181 { | 181 { |
182 struct type_brand_s * k1 = (struct type_brand_s *) sk1; | 182 struct type_brand_s * k1 = (struct type_brand_s *) sk1; |
183 struct type_brand_s * k2 = (struct type_brand_s *) sk2; | 183 struct type_brand_s * k2 = (struct type_brand_s *) sk2; |
184 | 184 |
185 int value = strcmp(k1->name, k2->name); | 185 int value = strcmp(k1->name, k2->name); |
186 if (value == 0) | 186 if (value == 0) |
187 return k2->seq - k1->seq; | 187 return k2->seq - k1->seq; |
188 else | 188 else |
189 return value; | 189 return value; |
190 } | 190 } |
191 | 191 |
192 /* All of the "unique_type" code is a hack to get around the sleazy | 192 /* All of the "unique_type" code is a hack to get around the sleazy |
193 implementation used to compile more than file. Currently gcc does | 193 implementation used to compile more than file. Currently gcc does |
279 case RECORD_TYPE: | 279 case RECORD_TYPE: |
280 case UNION_TYPE: | 280 case UNION_TYPE: |
281 case VECTOR_TYPE: | 281 case VECTOR_TYPE: |
282 case VOID_TYPE: | 282 case VOID_TYPE: |
283 return true; | 283 return true; |
284 | 284 |
285 default: | 285 default: |
286 return false; | 286 return false; |
287 } | 287 } |
288 } | 288 } |
289 | 289 |
290 /* Get the canon type of TYPE. If SEE_THRU_PTRS is true, remove all | 290 /* Get the canon type of TYPE. If SEE_THRU_PTRS is true, remove all |
291 the POINTER_TOs and if SEE_THRU_ARRAYS is true, remove all of the | 291 the POINTER_TOs and if SEE_THRU_ARRAYS is true, remove all of the |
292 ARRAY_OFs and POINTER_TOs. */ | 292 ARRAY_OFs and POINTER_TOs. */ |
293 | 293 |
294 static tree | 294 static tree |
295 get_canon_type (tree type, bool see_thru_ptrs, bool see_thru_arrays) | 295 get_canon_type (tree type, bool see_thru_ptrs, bool see_thru_arrays) |
296 { | 296 { |
297 splay_tree_node result; | 297 splay_tree_node result; |
298 /* Strip the *'s off. */ | 298 /* Strip the *'s off. */ |
299 if (!type || !type_to_consider (type)) | 299 if (!type || !type_to_consider (type)) |
300 return NULL; | 300 return NULL; |
301 | 301 |
302 type = TYPE_MAIN_VARIANT (type); | 302 type = TYPE_MAIN_VARIANT (type); |
303 if (see_thru_arrays) | 303 if (see_thru_arrays) |
304 while (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE) | 304 while (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE) |
305 type = TYPE_MAIN_VARIANT (TREE_TYPE (type)); | 305 type = TYPE_MAIN_VARIANT (TREE_TYPE (type)); |
306 | 306 |
307 else if (see_thru_ptrs) | 307 else if (see_thru_ptrs) |
308 while (POINTER_TYPE_P (type)) | 308 while (POINTER_TYPE_P (type)) |
309 type = TYPE_MAIN_VARIANT (TREE_TYPE (type)); | 309 type = TYPE_MAIN_VARIANT (TREE_TYPE (type)); |
310 | 310 |
311 result = splay_tree_lookup (type_to_canon_type, (splay_tree_key) type); | 311 result = splay_tree_lookup (type_to_canon_type, (splay_tree_key) type); |
312 | 312 |
313 if (result == NULL) | 313 if (result == NULL) |
314 return discover_unique_type (type); | 314 return discover_unique_type (type); |
315 else return (tree) result->value; | 315 else return (tree) result->value; |
316 } | 316 } |
317 | 317 |
329 | 329 |
330 /* Return 0 if TYPE is a record or union type. Return a positive | 330 /* Return 0 if TYPE is a record or union type. Return a positive |
331 number if TYPE is a pointer to a record or union. The number is | 331 number if TYPE is a pointer to a record or union. The number is |
332 the number of pointer types stripped to get to the record or union | 332 the number of pointer types stripped to get to the record or union |
333 type. Return -1 if TYPE is none of the above. */ | 333 type. Return -1 if TYPE is none of the above. */ |
334 | 334 |
335 int | 335 int |
336 ipa_type_escape_star_count_of_interesting_type (tree type) | 336 ipa_type_escape_star_count_of_interesting_type (tree type) |
337 { | 337 { |
338 int count = 0; | 338 int count = 0; |
339 /* Strip the *'s off. */ | 339 /* Strip the *'s off. */ |
340 if (!type) | 340 if (!type) |
341 return -1; | 341 return -1; |
345 type = TYPE_MAIN_VARIANT (TREE_TYPE (type)); | 345 type = TYPE_MAIN_VARIANT (TREE_TYPE (type)); |
346 count++; | 346 count++; |
347 } | 347 } |
348 | 348 |
349 /* We are interested in records, and unions only. */ | 349 /* We are interested in records, and unions only. */ |
350 if (TREE_CODE (type) == RECORD_TYPE | 350 if (TREE_CODE (type) == RECORD_TYPE |
351 || TREE_CODE (type) == QUAL_UNION_TYPE | 351 || TREE_CODE (type) == QUAL_UNION_TYPE |
352 || TREE_CODE (type) == UNION_TYPE) | 352 || TREE_CODE (type) == UNION_TYPE) |
353 return count; | 353 return count; |
354 else | 354 else |
355 return -1; | 355 return -1; |
356 } | 356 } |
357 | 357 |
358 | 358 |
359 /* Return 0 if TYPE is a record or union type. Return a positive | 359 /* Return 0 if TYPE is a record or union type. Return a positive |
360 number if TYPE is a pointer to a record or union. The number is | 360 number if TYPE is a pointer to a record or union. The number is |
361 the number of pointer types stripped to get to the record or union | 361 the number of pointer types stripped to get to the record or union |
362 type. Return -1 if TYPE is none of the above. */ | 362 type. Return -1 if TYPE is none of the above. */ |
363 | 363 |
364 int | 364 int |
365 ipa_type_escape_star_count_of_interesting_or_array_type (tree type) | 365 ipa_type_escape_star_count_of_interesting_or_array_type (tree type) |
366 { | 366 { |
367 int count = 0; | 367 int count = 0; |
368 /* Strip the *'s off. */ | 368 /* Strip the *'s off. */ |
369 if (!type) | 369 if (!type) |
370 return -1; | 370 return -1; |
374 type = TYPE_MAIN_VARIANT (TREE_TYPE (type)); | 374 type = TYPE_MAIN_VARIANT (TREE_TYPE (type)); |
375 count++; | 375 count++; |
376 } | 376 } |
377 | 377 |
378 /* We are interested in records, and unions only. */ | 378 /* We are interested in records, and unions only. */ |
379 if (TREE_CODE (type) == RECORD_TYPE | 379 if (TREE_CODE (type) == RECORD_TYPE |
380 || TREE_CODE (type) == QUAL_UNION_TYPE | 380 || TREE_CODE (type) == QUAL_UNION_TYPE |
381 || TREE_CODE (type) == UNION_TYPE) | 381 || TREE_CODE (type) == UNION_TYPE) |
382 return count; | 382 return count; |
383 else | 383 else |
384 return -1; | 384 return -1; |
385 } | 385 } |
386 | 386 |
387 | 387 |
388 /* Return true if the record, or union TYPE passed in escapes this | 388 /* Return true if the record, or union TYPE passed in escapes this |
389 compilation unit. Note that all of the pointer-to's are removed | 389 compilation unit. Note that all of the pointer-to's are removed |
390 before testing since these may not be correct. */ | 390 before testing since these may not be correct. */ |
391 | 391 |
392 bool | 392 bool |
393 ipa_type_escape_type_contained_p (tree type) | 393 ipa_type_escape_type_contained_p (tree type) |
394 { | 394 { |
395 if (!initialized) | 395 if (!initialized) |
396 return false; | 396 return false; |
397 return !bitmap_bit_p (global_types_full_escape, | 397 return !bitmap_bit_p (global_types_full_escape, |
398 get_canon_type_uid (type, true, false)); | 398 get_canon_type_uid (type, true, false)); |
399 } | 399 } |
400 | 400 |
401 /* Return true if a modification to a field of type FIELD_TYPE cannot | 401 /* Return true if a modification to a field of type FIELD_TYPE cannot |
402 clobber a record of RECORD_TYPE. */ | 402 clobber a record of RECORD_TYPE. */ |
403 | 403 |
404 bool | 404 bool |
405 ipa_type_escape_field_does_not_clobber_p (tree record_type, tree field_type) | 405 ipa_type_escape_field_does_not_clobber_p (tree record_type, tree field_type) |
406 { | 406 { |
407 splay_tree_node result; | 407 splay_tree_node result; |
408 int uid; | 408 int uid; |
409 | 409 |
410 if (!initialized) | 410 if (!initialized) |
411 return false; | 411 return false; |
412 | 412 |
413 /* Strip off all of the pointer tos on the record type. Strip the | 413 /* Strip off all of the pointer tos on the record type. Strip the |
414 same number of pointer tos from the field type. If the field | 414 same number of pointer tos from the field type. If the field |
416 record_type = TYPE_MAIN_VARIANT (record_type); | 416 record_type = TYPE_MAIN_VARIANT (record_type); |
417 field_type = TYPE_MAIN_VARIANT (field_type); | 417 field_type = TYPE_MAIN_VARIANT (field_type); |
418 while (POINTER_TYPE_P (record_type)) | 418 while (POINTER_TYPE_P (record_type)) |
419 { | 419 { |
420 record_type = TYPE_MAIN_VARIANT (TREE_TYPE (record_type)); | 420 record_type = TYPE_MAIN_VARIANT (TREE_TYPE (record_type)); |
421 if (POINTER_TYPE_P (field_type)) | 421 if (POINTER_TYPE_P (field_type)) |
422 field_type = TYPE_MAIN_VARIANT (TREE_TYPE (field_type)); | 422 field_type = TYPE_MAIN_VARIANT (TREE_TYPE (field_type)); |
423 else | 423 else |
424 /* However, if field_type is a union, this quick test is not | 424 /* However, if field_type is a union, this quick test is not |
425 correct since one of the variants of the union may be a | 425 correct since one of the variants of the union may be a |
426 pointer to type and we cannot see across that here. So we | 426 pointer to type and we cannot see across that here. So we |
427 just strip the remaining pointer tos off the record type | 427 just strip the remaining pointer tos off the record type |
428 and fall thru to the more precise code. */ | 428 and fall thru to the more precise code. */ |
429 if (TREE_CODE (field_type) == QUAL_UNION_TYPE | 429 if (TREE_CODE (field_type) == QUAL_UNION_TYPE |
430 || TREE_CODE (field_type) == UNION_TYPE) | 430 || TREE_CODE (field_type) == UNION_TYPE) |
431 { | 431 { |
432 while (POINTER_TYPE_P (record_type)) | 432 while (POINTER_TYPE_P (record_type)) |
433 record_type = TYPE_MAIN_VARIANT (TREE_TYPE (record_type)); | 433 record_type = TYPE_MAIN_VARIANT (TREE_TYPE (record_type)); |
434 break; | 434 break; |
435 } | 435 } |
436 else | 436 else |
437 return true; | 437 return true; |
438 } | 438 } |
439 | 439 |
440 record_type = get_canon_type (record_type, true, true); | 440 record_type = get_canon_type (record_type, true, true); |
441 /* The record type must be contained. The field type may | 441 /* The record type must be contained. The field type may |
442 escape. */ | 442 escape. */ |
443 if (!ipa_type_escape_type_contained_p (record_type)) | 443 if (!ipa_type_escape_type_contained_p (record_type)) |
444 return false; | 444 return false; |
445 | 445 |
446 uid = TYPE_UID (record_type); | 446 uid = TYPE_UID (record_type); |
447 result = splay_tree_lookup (uid_to_addressof_down_map, (splay_tree_key) uid); | 447 result = splay_tree_lookup (uid_to_addressof_down_map, (splay_tree_key) uid); |
448 | 448 |
449 if (result) | 449 if (result) |
450 { | 450 { |
451 bitmap field_type_map = (bitmap) result->value; | 451 bitmap field_type_map = (bitmap) result->value; |
452 uid = get_canon_type_uid (field_type, true, true); | 452 uid = get_canon_type_uid (field_type, true, true); |
453 /* If the bit is there, the address was taken. If not, it | 453 /* If the bit is there, the address was taken. If not, it |
454 wasn't. */ | 454 wasn't. */ |
468 { | 468 { |
469 bitmap map = NULL; | 469 bitmap map = NULL; |
470 int uid; | 470 int uid; |
471 | 471 |
472 type = get_canon_type (type, true, true); | 472 type = get_canon_type (type, true, true); |
473 if (!type) | 473 if (!type) |
474 return NULL; | 474 return NULL; |
475 | 475 |
476 switch (escape_status) | 476 switch (escape_status) |
477 { | 477 { |
478 case EXPOSED_PARAMETER: | 478 case EXPOSED_PARAMETER: |
479 map = global_types_exposed_parameter; | 479 map = global_types_exposed_parameter; |
480 break; | 480 break; |
481 case FULL_ESCAPE: | 481 case FULL_ESCAPE: |
492 if (escape_status == FULL_ESCAPE) | 492 if (escape_status == FULL_ESCAPE) |
493 { | 493 { |
494 /* Efficiency hack. When things are bad, do not mess around | 494 /* Efficiency hack. When things are bad, do not mess around |
495 with this type anymore. */ | 495 with this type anymore. */ |
496 bitmap_set_bit (global_types_exposed_parameter, uid); | 496 bitmap_set_bit (global_types_exposed_parameter, uid); |
497 } | 497 } |
498 } | 498 } |
499 return type; | 499 return type; |
500 } | 500 } |
501 | 501 |
502 /* Add interesting TYPE to the suspect type set. If the set is | 502 /* Add interesting TYPE to the suspect type set. If the set is |
503 EXPOSED_PARAMETER and the TYPE is a pointer type, the set is | 503 EXPOSED_PARAMETER and the TYPE is a pointer type, the set is |
504 changed to FULL_ESCAPE. */ | 504 changed to FULL_ESCAPE. */ |
505 | 505 |
506 static void | 506 static void |
507 mark_interesting_type (tree type, enum escape_t escape_status) | 507 mark_interesting_type (tree type, enum escape_t escape_status) |
508 { | 508 { |
509 if (!type) return; | 509 if (!type) return; |
510 if (ipa_type_escape_star_count_of_interesting_type (type) >= 0) | 510 if (ipa_type_escape_star_count_of_interesting_type (type) >= 0) |
511 { | 511 { |
520 } | 520 } |
521 } | 521 } |
522 | 522 |
523 /* Return true if PARENT is supertype of CHILD. Both types must be | 523 /* Return true if PARENT is supertype of CHILD. Both types must be |
524 known to be structures or unions. */ | 524 known to be structures or unions. */ |
525 | 525 |
526 static bool | 526 static bool |
527 parent_type_p (tree parent, tree child) | 527 parent_type_p (tree parent, tree child) |
528 { | 528 { |
529 int i; | 529 int i; |
530 tree binfo, base_binfo; | 530 tree binfo, base_binfo; |
531 if (TYPE_BINFO (parent)) | 531 if (TYPE_BINFO (parent)) |
532 for (binfo = TYPE_BINFO (parent), i = 0; | 532 for (binfo = TYPE_BINFO (parent), i = 0; |
533 BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) | 533 BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) |
534 { | 534 { |
535 tree binfotype = BINFO_TYPE (base_binfo); | 535 tree binfotype = BINFO_TYPE (base_binfo); |
536 if (binfotype == child) | 536 if (binfotype == child) |
537 return true; | 537 return true; |
538 else if (parent_type_p (binfotype, child)) | 538 else if (parent_type_p (binfotype, child)) |
539 return true; | 539 return true; |
540 } | 540 } |
541 if (TREE_CODE (parent) == UNION_TYPE | 541 if (TREE_CODE (parent) == UNION_TYPE |
542 || TREE_CODE (parent) == QUAL_UNION_TYPE) | 542 || TREE_CODE (parent) == QUAL_UNION_TYPE) |
543 { | 543 { |
544 tree field; | 544 tree field; |
545 /* Search all of the variants in the union to see if one of them | 545 /* Search all of the variants in the union to see if one of them |
546 is the child. */ | 546 is the child. */ |
547 for (field = TYPE_FIELDS (parent); | 547 for (field = TYPE_FIELDS (parent); |
549 field = TREE_CHAIN (field)) | 549 field = TREE_CHAIN (field)) |
550 { | 550 { |
551 tree field_type; | 551 tree field_type; |
552 if (TREE_CODE (field) != FIELD_DECL) | 552 if (TREE_CODE (field) != FIELD_DECL) |
553 continue; | 553 continue; |
554 | 554 |
555 field_type = TREE_TYPE (field); | 555 field_type = TREE_TYPE (field); |
556 if (field_type == child) | 556 if (field_type == child) |
557 return true; | 557 return true; |
558 } | 558 } |
559 | 559 |
560 /* If we did not find it, recursively ask the variants if one of | 560 /* If we did not find it, recursively ask the variants if one of |
561 their children is the child type. */ | 561 their children is the child type. */ |
564 field = TREE_CHAIN (field)) | 564 field = TREE_CHAIN (field)) |
565 { | 565 { |
566 tree field_type; | 566 tree field_type; |
567 if (TREE_CODE (field) != FIELD_DECL) | 567 if (TREE_CODE (field) != FIELD_DECL) |
568 continue; | 568 continue; |
569 | 569 |
570 field_type = TREE_TYPE (field); | 570 field_type = TREE_TYPE (field); |
571 if (TREE_CODE (field_type) == RECORD_TYPE | 571 if (TREE_CODE (field_type) == RECORD_TYPE |
572 || TREE_CODE (field_type) == QUAL_UNION_TYPE | 572 || TREE_CODE (field_type) == QUAL_UNION_TYPE |
573 || TREE_CODE (field_type) == UNION_TYPE) | 573 || TREE_CODE (field_type) == UNION_TYPE) |
574 if (parent_type_p (field_type, child)) | 574 if (parent_type_p (field_type, child)) |
575 return true; | 575 return true; |
576 } | 576 } |
577 } | 577 } |
578 | 578 |
579 if (TREE_CODE (parent) == RECORD_TYPE) | 579 if (TREE_CODE (parent) == RECORD_TYPE) |
580 { | 580 { |
581 tree field; | 581 tree field; |
582 for (field = TYPE_FIELDS (parent); | 582 for (field = TYPE_FIELDS (parent); |
583 field; | 583 field; |
584 field = TREE_CHAIN (field)) | 584 field = TREE_CHAIN (field)) |
585 { | 585 { |
586 tree field_type; | 586 tree field_type; |
587 if (TREE_CODE (field) != FIELD_DECL) | 587 if (TREE_CODE (field) != FIELD_DECL) |
588 continue; | 588 continue; |
589 | 589 |
590 field_type = TREE_TYPE (field); | 590 field_type = TREE_TYPE (field); |
591 if (field_type == child) | 591 if (field_type == child) |
592 return true; | 592 return true; |
593 /* You can only cast to the first field so if it does not | 593 /* You can only cast to the first field so if it does not |
594 match, quit. */ | 594 match, quit. */ |
595 if (TREE_CODE (field_type) == RECORD_TYPE | 595 if (TREE_CODE (field_type) == RECORD_TYPE |
596 || TREE_CODE (field_type) == QUAL_UNION_TYPE | 596 || TREE_CODE (field_type) == QUAL_UNION_TYPE |
597 || TREE_CODE (field_type) == UNION_TYPE) | 597 || TREE_CODE (field_type) == UNION_TYPE) |
598 { | 598 { |
599 if (parent_type_p (field_type, child)) | 599 if (parent_type_p (field_type, child)) |
600 return true; | 600 return true; |
601 else | 601 else |
602 break; | 602 break; |
603 } | 603 } |
604 } | 604 } |
605 } | 605 } |
606 return false; | 606 return false; |
607 } | 607 } |
608 | 608 |
609 /* Return the number of pointer tos for TYPE and return TYPE with all | 609 /* Return the number of pointer tos for TYPE and return TYPE with all |
610 of these stripped off. */ | 610 of these stripped off. */ |
611 | 611 |
612 static int | 612 static int |
613 count_stars (tree* type_ptr) | 613 count_stars (tree* type_ptr) |
614 { | 614 { |
615 tree type = *type_ptr; | 615 tree type = *type_ptr; |
616 int i = 0; | 616 int i = 0; |
617 type = TYPE_MAIN_VARIANT (type); | 617 type = TYPE_MAIN_VARIANT (type); |
644 static enum cast_type | 644 static enum cast_type |
645 check_cast_type (tree to_type, tree from_type) | 645 check_cast_type (tree to_type, tree from_type) |
646 { | 646 { |
647 int to_stars = count_stars (&to_type); | 647 int to_stars = count_stars (&to_type); |
648 int from_stars = count_stars (&from_type); | 648 int from_stars = count_stars (&from_type); |
649 if (to_stars != from_stars) | 649 if (to_stars != from_stars) |
650 return CT_SIDEWAYS; | 650 return CT_SIDEWAYS; |
651 | 651 |
652 if (to_type == from_type) | 652 if (to_type == from_type) |
653 return CT_USELESS; | 653 return CT_USELESS; |
654 | 654 |
655 if (parent_type_p (to_type, from_type)) return CT_UP; | 655 if (parent_type_p (to_type, from_type)) return CT_UP; |
656 if (parent_type_p (from_type, to_type)) return CT_DOWN; | 656 if (parent_type_p (from_type, to_type)) return CT_DOWN; |
657 return CT_SIDEWAYS; | 657 return CT_SIDEWAYS; |
658 } | 658 } |
659 | 659 |
660 /* This function returns nonzero if VAR is result of call | 660 /* This function returns nonzero if VAR is result of call |
661 to malloc function. */ | 661 to malloc function. */ |
662 | 662 |
663 static bool | 663 static bool |
664 is_malloc_result (tree var) | 664 is_malloc_result (tree var) |
665 { | 665 { |
666 gimple def_stmt; | 666 gimple def_stmt; |
667 | 667 |
668 if (!var) | 668 if (!var) |
669 return false; | 669 return false; |
670 | 670 |
671 if (SSA_NAME_IS_DEFAULT_DEF (var)) | 671 if (SSA_NAME_IS_DEFAULT_DEF (var)) |
672 return false; | 672 return false; |
673 | 673 |
674 def_stmt = SSA_NAME_DEF_STMT (var); | 674 def_stmt = SSA_NAME_DEF_STMT (var); |
675 | 675 |
676 if (!is_gimple_call (def_stmt)) | 676 if (!is_gimple_call (def_stmt)) |
677 return false; | 677 return false; |
678 | 678 |
679 if (var != gimple_call_lhs (def_stmt)) | 679 if (var != gimple_call_lhs (def_stmt)) |
680 return false; | 680 return false; |
683 | 683 |
684 } | 684 } |
685 | 685 |
686 /* Check a cast FROM this variable, TO_TYPE. Mark the escaping types | 686 /* Check a cast FROM this variable, TO_TYPE. Mark the escaping types |
687 if appropriate. Returns cast_type as detected. */ | 687 if appropriate. Returns cast_type as detected. */ |
688 | 688 |
689 static enum cast_type | 689 static enum cast_type |
690 check_cast (tree to_type, tree from) | 690 check_cast (tree to_type, tree from) |
691 { | 691 { |
692 tree from_type = get_canon_type (TREE_TYPE (from), false, false); | 692 tree from_type = get_canon_type (TREE_TYPE (from), false, false); |
693 bool to_interesting_type, from_interesting_type; | 693 bool to_interesting_type, from_interesting_type; |
694 enum cast_type cast = CT_NO_CAST; | 694 enum cast_type cast = CT_NO_CAST; |
695 | 695 |
696 to_type = get_canon_type (to_type, false, false); | 696 to_type = get_canon_type (to_type, false, false); |
697 if (!from_type || !to_type || from_type == to_type) | 697 if (!from_type || !to_type || from_type == to_type) |
698 return cast; | 698 return cast; |
699 | 699 |
700 to_interesting_type = | 700 to_interesting_type = |
701 ipa_type_escape_star_count_of_interesting_type (to_type) >= 0; | 701 ipa_type_escape_star_count_of_interesting_type (to_type) >= 0; |
702 from_interesting_type = | 702 from_interesting_type = |
703 ipa_type_escape_star_count_of_interesting_type (from_type) >= 0; | 703 ipa_type_escape_star_count_of_interesting_type (from_type) >= 0; |
704 | 704 |
705 if (to_interesting_type) | 705 if (to_interesting_type) |
706 if (from_interesting_type) | 706 if (from_interesting_type) |
707 { | 707 { |
708 /* Both types are interesting. This can be one of four types | 708 /* Both types are interesting. This can be one of four types |
709 of cast: useless, up, down, or sideways. We do not care | 709 of cast: useless, up, down, or sideways. We do not care |
710 about up or useless. Sideways casts are always bad and | 710 about up or useless. Sideways casts are always bad and |
711 both sides get marked as escaping. Downcasts are not | 711 both sides get marked as escaping. Downcasts are not |
712 interesting here because if type is marked as escaping, all | 712 interesting here because if type is marked as escaping, all |
713 of its subtypes escape. */ | 713 of its subtypes escape. */ |
714 cast = check_cast_type (to_type, from_type); | 714 cast = check_cast_type (to_type, from_type); |
715 switch (cast) | 715 switch (cast) |
716 { | 716 { |
717 case CT_UP: | 717 case CT_UP: |
718 case CT_USELESS: | 718 case CT_USELESS: |
719 case CT_DOWN: | 719 case CT_DOWN: |
720 break; | 720 break; |
729 } | 729 } |
730 } | 730 } |
731 else | 731 else |
732 { | 732 { |
733 /* This code excludes two cases from marking as escaped: | 733 /* This code excludes two cases from marking as escaped: |
734 | 734 |
735 1. if this is a cast of index of array of structures/unions | 735 1. if this is a cast of index of array of structures/unions |
736 that happens before accessing array element, we should not | 736 that happens before accessing array element, we should not |
737 mark it as escaped. | 737 mark it as escaped. |
738 2. if this is a cast from the local that is a result from a | 738 2. if this is a cast from the local that is a result from a |
739 call to malloc, do not mark the cast as bad. | 739 call to malloc, do not mark the cast as bad. |
740 | 740 |
741 */ | 741 */ |
742 | 742 |
743 if (POINTER_TYPE_P (to_type) && !POINTER_TYPE_P (from_type)) | 743 if (POINTER_TYPE_P (to_type) && !POINTER_TYPE_P (from_type)) |
744 cast = CT_FROM_NON_P; | 744 cast = CT_FROM_NON_P; |
745 else if (TREE_CODE (from) == SSA_NAME | 745 else if (TREE_CODE (from) == SSA_NAME |
746 && is_malloc_result (from)) | 746 && is_malloc_result (from)) |
747 cast = CT_FROM_MALLOC; | 747 cast = CT_FROM_MALLOC; |
748 else | 748 else |
749 { | 749 { |
750 cast = CT_FROM_P_BAD; | 750 cast = CT_FROM_P_BAD; |
784 | 784 |
785 if (!cast) | 785 if (!cast) |
786 cast = CT_NO_CAST; | 786 cast = CT_NO_CAST; |
787 | 787 |
788 return cast; | 788 return cast; |
789 } | 789 } |
790 | 790 |
791 | 791 |
792 typedef struct cast | 792 typedef struct cast |
793 { | 793 { |
794 int type; | 794 int type; |
795 gimple stmt; | 795 gimple stmt; |
796 } cast_t; | 796 } cast_t; |
797 | 797 |
798 /* This function is a callback for walk_use_def_chains function called | 798 /* This function is a callback for walk_use_def_chains function called |
799 from is_array_access_through_pointer_and_index. */ | 799 from is_array_access_through_pointer_and_index. */ |
800 | 800 |
801 static bool | 801 static bool |
802 is_cast_from_non_pointer (tree var, gimple def_stmt, void *data) | 802 is_cast_from_non_pointer (tree var, gimple def_stmt, void *data) |
803 { | 803 { |
804 if (!def_stmt || !var) | 804 if (!def_stmt || !var) |
805 return false; | 805 return false; |
806 | 806 |
807 if (gimple_code (def_stmt) == GIMPLE_PHI) | 807 if (gimple_code (def_stmt) == GIMPLE_PHI) |
808 return false; | 808 return false; |
809 | 809 |
810 if (SSA_NAME_IS_DEFAULT_DEF (var)) | 810 if (SSA_NAME_IS_DEFAULT_DEF (var)) |
811 return false; | 811 return false; |
812 | 812 |
813 if (is_gimple_assign (def_stmt)) | 813 if (is_gimple_assign (def_stmt)) |
814 { | 814 { |
815 use_operand_p use_p; | 815 use_operand_p use_p; |
816 ssa_op_iter iter; | 816 ssa_op_iter iter; |
817 unsigned int cast = look_for_casts_stmt (def_stmt); | 817 unsigned int cast = look_for_casts_stmt (def_stmt); |
818 | 818 |
819 /* Check that only one cast happened, and it's of non-pointer | 819 /* Check that only one cast happened, and it's of non-pointer |
820 type. */ | 820 type. */ |
821 if ((cast & CT_FROM_NON_P) == (CT_FROM_NON_P) | 821 if ((cast & CT_FROM_NON_P) == (CT_FROM_NON_P) |
822 && (cast & ~(CT_FROM_NON_P)) == 0) | 822 && (cast & ~(CT_FROM_NON_P)) == 0) |
823 { | 823 { |
824 ((cast_t *)data)->stmt = def_stmt; | 824 ((cast_t *)data)->stmt = def_stmt; |
825 ((cast_t *)data)->type++; | 825 ((cast_t *)data)->type++; |
826 | 826 |
843 { | 843 { |
844 walk_use_def_chains (USE_FROM_PTR (use_p), | 844 walk_use_def_chains (USE_FROM_PTR (use_p), |
845 is_cast_from_non_pointer, data, false); | 845 is_cast_from_non_pointer, data, false); |
846 if (((cast_t*)data)->type == -1) | 846 if (((cast_t*)data)->type == -1) |
847 break; | 847 break; |
848 } | 848 } |
849 } | 849 } |
850 /* The cast is harmful. */ | 850 /* The cast is harmful. */ |
851 else | 851 else |
852 ((cast_t *)data)->type = -1; | 852 ((cast_t *)data)->type = -1; |
853 } | 853 } |
854 | 854 |
855 if (((cast_t*)data)->type == -1) | 855 if (((cast_t*)data)->type == -1) |
856 return true; | 856 return true; |
857 | 857 |
858 return false; | 858 return false; |
859 } | 859 } |
860 | 860 |
861 /* When array element a_p[i] is accessed through the pointer a_p | 861 /* When array element a_p[i] is accessed through the pointer a_p |
862 and index i, it's translated into the following sequence | 862 and index i, it's translated into the following sequence |
863 in gimple: | 863 in gimple: |
864 | 864 |
865 i.1_5 = (unsigned int) i_1; | 865 i.1_5 = (unsigned int) i_1; |
866 D.1605_6 = i.1_5 * 16; | 866 D.1605_6 = i.1_5 * 16; |
867 D.1606_7 = (struct str_t *) D.1605_6; | 867 D.1606_7 = (struct str_t *) D.1605_6; |
868 a_p.2_8 = a_p; | 868 a_p.2_8 = a_p; |
869 D.1608_9 = D.1606_7 + a_p.2_8; | 869 D.1608_9 = D.1606_7 + a_p.2_8; |
870 | 870 |
871 OP0 and OP1 are of the same pointer types and stand for | 871 OP0 and OP1 are of the same pointer types and stand for |
872 D.1606_7 and a_p.2_8 or vise versa. | 872 D.1606_7 and a_p.2_8 or vise versa. |
873 | 873 |
874 This function checks that: | 874 This function checks that: |
875 | 875 |
876 1. one of OP0 and OP1 (D.1606_7) has passed only one cast from | 876 1. one of OP0 and OP1 (D.1606_7) has passed only one cast from |
877 non-pointer type (D.1606_7 = (struct str_t *) D.1605_6;). | 877 non-pointer type (D.1606_7 = (struct str_t *) D.1605_6;). |
878 | 878 |
879 2. one of OP0 and OP1 which has passed the cast from | 879 2. one of OP0 and OP1 which has passed the cast from |
880 non-pointer type (D.1606_7), is actually generated by multiplication of | 880 non-pointer type (D.1606_7), is actually generated by multiplication of |
881 index by size of type to which both OP0 and OP1 point to | 881 index by size of type to which both OP0 and OP1 point to |
882 (in this case D.1605_6 = i.1_5 * 16; ). | 882 (in this case D.1605_6 = i.1_5 * 16; ). |
883 | 883 |
884 3. an address of def of the var to which was made cast (D.1605_6) | 884 3. an address of def of the var to which was made cast (D.1605_6) |
885 was not taken.(How can it happen?) | 885 was not taken.(How can it happen?) |
886 | 886 |
887 The following items are checked implicitly by the end of algorithm: | 887 The following items are checked implicitly by the end of algorithm: |
888 | 888 |
889 4. one of OP0 and OP1 (a_p.2_8) have never been cast | 889 4. one of OP0 and OP1 (a_p.2_8) have never been cast |
890 (because if it was cast to pointer type, its type, that is also | 890 (because if it was cast to pointer type, its type, that is also |
891 the type of OP0 and OP1, will be marked as escaped during | 891 the type of OP0 and OP1, will be marked as escaped during |
892 analysis of casting stmt (when check_cast() is called | 892 analysis of casting stmt (when check_cast() is called |
893 from scan_for_refs for this stmt)). | 893 from scan_for_refs for this stmt)). |
894 | 894 |
895 5. defs of OP0 and OP1 are not passed into externally visible function | 895 5. defs of OP0 and OP1 are not passed into externally visible function |
896 (because if they are passed then their type, that is also the type of OP0 | 896 (because if they are passed then their type, that is also the type of OP0 |
897 and OP1, will be marked and escaped during check_call function called from | 897 and OP1, will be marked and escaped during check_call function called from |
898 scan_for_refs with call stmt). | 898 scan_for_refs with call stmt). |
899 | 899 |
900 In total, 1-5 guaranty that it's an access to array by pointer and index. | 900 In total, 1-5 guaranty that it's an access to array by pointer and index. |
901 | 901 |
902 */ | 902 */ |
903 | 903 |
904 bool | 904 bool |
905 is_array_access_through_pointer_and_index (enum tree_code code, tree op0, | 905 is_array_access_through_pointer_and_index (enum tree_code code, tree op0, |
906 tree op1, tree *base, tree *offset, | 906 tree op1, tree *base, tree *offset, |
907 gimple *offset_cast_stmt) | 907 gimple *offset_cast_stmt) |
908 { | 908 { |
909 tree before_cast; | 909 tree before_cast; |
910 gimple before_cast_def_stmt; | 910 gimple before_cast_def_stmt; |
943 visited_stmts = pointer_set_create (); | 943 visited_stmts = pointer_set_create (); |
944 walk_use_def_chains (op0, is_cast_from_non_pointer,(void *)(&op0_cast), | 944 walk_use_def_chains (op0, is_cast_from_non_pointer,(void *)(&op0_cast), |
945 false); | 945 false); |
946 pointer_set_destroy (visited_stmts); | 946 pointer_set_destroy (visited_stmts); |
947 | 947 |
948 visited_stmts = pointer_set_create (); | 948 visited_stmts = pointer_set_create (); |
949 walk_use_def_chains (op1, is_cast_from_non_pointer,(void *)(&op1_cast), | 949 walk_use_def_chains (op1, is_cast_from_non_pointer,(void *)(&op1_cast), |
950 false); | 950 false); |
951 pointer_set_destroy (visited_stmts); | 951 pointer_set_destroy (visited_stmts); |
952 | 952 |
953 if (op0_cast.type == 1 && op1_cast.type == 0) | 953 if (op0_cast.type == 1 && op1_cast.type == 0) |
957 *offset_cast_stmt = op0_cast.stmt; | 957 *offset_cast_stmt = op0_cast.stmt; |
958 } | 958 } |
959 else if (op0_cast.type == 0 && op1_cast.type == 1) | 959 else if (op0_cast.type == 0 && op1_cast.type == 1) |
960 { | 960 { |
961 *base = op0; | 961 *base = op0; |
962 *offset = op1; | 962 *offset = op1; |
963 *offset_cast_stmt = op1_cast.stmt; | 963 *offset_cast_stmt = op1_cast.stmt; |
964 } | 964 } |
965 else | 965 else |
966 return false; | 966 return false; |
967 } | 967 } |
968 | 968 |
969 /* Check 2. | 969 /* Check 2. |
970 offset_cast_stmt is of the form: | 970 offset_cast_stmt is of the form: |
971 D.1606_7 = (struct str_t *) D.1605_6; */ | 971 D.1606_7 = (struct str_t *) D.1605_6; */ |
972 | 972 |
973 if (*offset_cast_stmt) | 973 if (*offset_cast_stmt) |
974 { | 974 { |
975 before_cast = SINGLE_SSA_TREE_OPERAND (*offset_cast_stmt, SSA_OP_USE); | 975 before_cast = SINGLE_SSA_TREE_OPERAND (*offset_cast_stmt, SSA_OP_USE); |
976 if (!before_cast) | 976 if (!before_cast) |
977 return false; | 977 return false; |
978 | 978 |
979 if (SSA_NAME_IS_DEFAULT_DEF (before_cast)) | 979 if (SSA_NAME_IS_DEFAULT_DEF (before_cast)) |
980 return false; | 980 return false; |
981 | 981 |
982 before_cast_def_stmt = SSA_NAME_DEF_STMT (before_cast); | 982 before_cast_def_stmt = SSA_NAME_DEF_STMT (before_cast); |
983 if (!before_cast_def_stmt) | 983 if (!before_cast_def_stmt) |
984 return false; | 984 return false; |
985 } | 985 } |
986 else | 986 else |
987 before_cast_def_stmt = SSA_NAME_DEF_STMT (*offset); | 987 before_cast_def_stmt = SSA_NAME_DEF_STMT (*offset); |
988 | 988 |
989 /* before_cast_def_stmt should be of the form: | 989 /* before_cast_def_stmt should be of the form: |
990 D.1605_6 = i.1_5 * 16; */ | 990 D.1605_6 = i.1_5 * 16; */ |
991 | 991 |
992 if (is_gimple_assign (before_cast_def_stmt)) | 992 if (is_gimple_assign (before_cast_def_stmt)) |
993 { | 993 { |
994 /* We expect temporary here. */ | 994 /* We expect temporary here. */ |
995 if (!is_gimple_reg (gimple_assign_lhs (before_cast_def_stmt))) | 995 if (!is_gimple_reg (gimple_assign_lhs (before_cast_def_stmt))) |
996 return false; | 996 return false; |
997 | 997 |
998 if (gimple_assign_rhs_code (before_cast_def_stmt) == MULT_EXPR) | 998 if (gimple_assign_rhs_code (before_cast_def_stmt) == MULT_EXPR) |
999 { | 999 { |
1000 tree arg0 = gimple_assign_rhs1 (before_cast_def_stmt); | 1000 tree arg0 = gimple_assign_rhs1 (before_cast_def_stmt); |
1001 tree arg1 = gimple_assign_rhs2 (before_cast_def_stmt); | 1001 tree arg1 = gimple_assign_rhs2 (before_cast_def_stmt); |
1002 tree unit_size = | 1002 tree unit_size = |
1003 TYPE_SIZE_UNIT (TREE_TYPE (TYPE_MAIN_VARIANT (TREE_TYPE (op0)))); | 1003 TYPE_SIZE_UNIT (TREE_TYPE (TYPE_MAIN_VARIANT (TREE_TYPE (op0)))); |
1004 | 1004 |
1005 if (!(CONSTANT_CLASS_P (arg0) | 1005 if (!(CONSTANT_CLASS_P (arg0) |
1006 && simple_cst_equal (arg0, unit_size)) | 1006 && simple_cst_equal (arg0, unit_size)) |
1007 && !(CONSTANT_CLASS_P (arg1) | 1007 && !(CONSTANT_CLASS_P (arg1) |
1008 && simple_cst_equal (arg1, unit_size))) | 1008 && simple_cst_equal (arg1, unit_size))) |
1009 return false; | 1009 return false; |
1010 } | 1010 } |
1011 else | 1011 else |
1012 return false; | 1012 return false; |
1013 } | 1013 } |
1014 else | 1014 else |
1022 } | 1022 } |
1023 | 1023 |
1024 /* Register the parameter and return types of function FN. The type | 1024 /* Register the parameter and return types of function FN. The type |
1025 ESCAPES if the function is visible outside of the compilation | 1025 ESCAPES if the function is visible outside of the compilation |
1026 unit. */ | 1026 unit. */ |
1027 static void | 1027 static void |
1028 check_function_parameter_and_return_types (tree fn, bool escapes) | 1028 check_function_parameter_and_return_types (tree fn, bool escapes) |
1029 { | 1029 { |
1030 tree arg; | 1030 tree arg; |
1031 | 1031 |
1032 if (TYPE_ARG_TYPES (TREE_TYPE (fn))) | 1032 if (TYPE_ARG_TYPES (TREE_TYPE (fn))) |
1033 { | 1033 { |
1034 for (arg = TYPE_ARG_TYPES (TREE_TYPE (fn)); | 1034 for (arg = TYPE_ARG_TYPES (TREE_TYPE (fn)); |
1035 arg && TREE_VALUE (arg) != void_type_node; | 1035 arg && TREE_VALUE (arg) != void_type_node; |
1036 arg = TREE_CHAIN (arg)) | 1036 arg = TREE_CHAIN (arg)) |
1055 } | 1055 } |
1056 } | 1056 } |
1057 if (escapes) | 1057 if (escapes) |
1058 { | 1058 { |
1059 tree type = get_canon_type (TREE_TYPE (TREE_TYPE (fn)), false, false); | 1059 tree type = get_canon_type (TREE_TYPE (TREE_TYPE (fn)), false, false); |
1060 mark_interesting_type (type, EXPOSED_PARAMETER); | 1060 mark_interesting_type (type, EXPOSED_PARAMETER); |
1061 } | 1061 } |
1062 } | 1062 } |
1063 | 1063 |
1064 /* Return true if the variable T is the right kind of static variable to | 1064 /* Return true if the variable T is the right kind of static variable to |
1065 perform compilation unit scope escape analysis. */ | 1065 perform compilation unit scope escape analysis. */ |
1078 return; | 1078 return; |
1079 } | 1079 } |
1080 | 1080 |
1081 /* Do not want to do anything with volatile except mark any | 1081 /* Do not want to do anything with volatile except mark any |
1082 function that uses one to be not const or pure. */ | 1082 function that uses one to be not const or pure. */ |
1083 if (TREE_THIS_VOLATILE (t)) | 1083 if (TREE_THIS_VOLATILE (t)) |
1084 return; | 1084 return; |
1085 | 1085 |
1086 /* Do not care about a local automatic that is not static. */ | 1086 /* Do not care about a local automatic that is not static. */ |
1087 if (!TREE_STATIC (t) && !DECL_EXTERNAL (t)) | 1087 if (!TREE_STATIC (t) && !DECL_EXTERNAL (t)) |
1088 return; | 1088 return; |
1091 { | 1091 { |
1092 /* If the front end set the variable to be READONLY and | 1092 /* If the front end set the variable to be READONLY and |
1093 constant, we can allow this variable in pure or const | 1093 constant, we can allow this variable in pure or const |
1094 functions but the scope is too large for our analysis to set | 1094 functions but the scope is too large for our analysis to set |
1095 these bits ourselves. */ | 1095 these bits ourselves. */ |
1096 | 1096 |
1097 if (TREE_READONLY (t) | 1097 if (TREE_READONLY (t) |
1098 && DECL_INITIAL (t) | 1098 && DECL_INITIAL (t) |
1099 && is_gimple_min_invariant (DECL_INITIAL (t))) | 1099 && is_gimple_min_invariant (DECL_INITIAL (t))) |
1100 ; /* Read of a constant, do not change the function state. */ | 1100 ; /* Read of a constant, do not change the function state. */ |
1101 else | 1101 else |
1102 { | 1102 { |
1103 /* The type escapes for all public and externs. */ | 1103 /* The type escapes for all public and externs. */ |
1104 mark_interesting_type (type, FULL_ESCAPE); | 1104 mark_interesting_type (type, FULL_ESCAPE); |
1105 } | 1105 } |
1106 } | 1106 } |
1118 escaping. */ | 1118 escaping. */ |
1119 if (TREE_CODE (t) == FUNCTION_DECL) | 1119 if (TREE_CODE (t) == FUNCTION_DECL) |
1120 check_function_parameter_and_return_types (t, true); | 1120 check_function_parameter_and_return_types (t, true); |
1121 | 1121 |
1122 else if (TREE_CODE (t) == VAR_DECL) | 1122 else if (TREE_CODE (t) == VAR_DECL) |
1123 has_proper_scope_for_analysis (t); | 1123 has_proper_scope_for_analysis (t); |
1124 } | 1124 } |
1125 | 1125 |
1126 /* Examine tree T for references. */ | 1126 /* Examine tree T for references. */ |
1127 | 1127 |
1128 static void | 1128 static void |
1129 check_tree (tree t) | 1129 check_tree (tree t) |
1130 { | 1130 { |
1131 if ((TREE_CODE (t) == EXC_PTR_EXPR) || (TREE_CODE (t) == FILTER_EXPR)) | |
1132 return; | |
1133 | |
1134 /* We want to catch here also REALPART_EXPR and IMAGEPART_EXPR, | 1131 /* We want to catch here also REALPART_EXPR and IMAGEPART_EXPR, |
1135 but they already included in handled_component_p. */ | 1132 but they already included in handled_component_p. */ |
1136 while (handled_component_p (t)) | 1133 while (handled_component_p (t)) |
1137 { | 1134 { |
1138 if (TREE_CODE (t) == ARRAY_REF) | 1135 if (TREE_CODE (t) == ARRAY_REF) |
1157 mark_interesting_addressof (tree to_type, tree from_type) | 1154 mark_interesting_addressof (tree to_type, tree from_type) |
1158 { | 1155 { |
1159 int from_uid; | 1156 int from_uid; |
1160 int to_uid; | 1157 int to_uid; |
1161 bitmap type_map; | 1158 bitmap type_map; |
1162 splay_tree_node result; | 1159 splay_tree_node result; |
1163 | 1160 |
1164 from_type = get_canon_type (from_type, false, false); | 1161 from_type = get_canon_type (from_type, false, false); |
1165 to_type = get_canon_type (to_type, false, false); | 1162 to_type = get_canon_type (to_type, false, false); |
1166 | 1163 |
1167 if (!from_type || !to_type) | 1164 if (!from_type || !to_type) |
1168 return; | 1165 return; |
1169 | 1166 |
1170 from_uid = TYPE_UID (from_type); | 1167 from_uid = TYPE_UID (from_type); |
1171 to_uid = TYPE_UID (to_type); | 1168 to_uid = TYPE_UID (to_type); |
1172 | 1169 |
1173 gcc_assert (ipa_type_escape_star_count_of_interesting_type (from_type) == 0); | 1170 gcc_assert (ipa_type_escape_star_count_of_interesting_type (from_type) == 0); |
1174 | 1171 |
1175 /* Process the Y into X map pointer. */ | 1172 /* Process the Y into X map pointer. */ |
1176 result = splay_tree_lookup (uid_to_addressof_down_map, | 1173 result = splay_tree_lookup (uid_to_addressof_down_map, |
1177 (splay_tree_key) from_uid); | 1174 (splay_tree_key) from_uid); |
1178 | 1175 |
1179 if (result) | 1176 if (result) |
1180 type_map = (bitmap) result->value; | 1177 type_map = (bitmap) result->value; |
1181 else | 1178 else |
1182 { | 1179 { |
1183 type_map = BITMAP_ALLOC (&ipa_obstack); | 1180 type_map = BITMAP_ALLOC (&ipa_obstack); |
1184 splay_tree_insert (uid_to_addressof_down_map, | 1181 splay_tree_insert (uid_to_addressof_down_map, |
1185 from_uid, | 1182 from_uid, |
1186 (splay_tree_value)type_map); | 1183 (splay_tree_value)type_map); |
1187 } | 1184 } |
1188 bitmap_set_bit (type_map, TYPE_UID (to_type)); | 1185 bitmap_set_bit (type_map, TYPE_UID (to_type)); |
1189 | 1186 |
1190 /* Process the X into Y reverse map pointer. */ | 1187 /* Process the X into Y reverse map pointer. */ |
1191 result = | 1188 result = |
1192 splay_tree_lookup (uid_to_addressof_up_map, (splay_tree_key) to_uid); | 1189 splay_tree_lookup (uid_to_addressof_up_map, (splay_tree_key) to_uid); |
1193 | 1190 |
1194 if (result) | 1191 if (result) |
1195 type_map = (bitmap) result->value; | 1192 type_map = (bitmap) result->value; |
1196 else | 1193 else |
1197 { | 1194 { |
1198 type_map = BITMAP_ALLOC (&ipa_obstack); | 1195 type_map = BITMAP_ALLOC (&ipa_obstack); |
1199 splay_tree_insert (uid_to_addressof_up_map, | 1196 splay_tree_insert (uid_to_addressof_up_map, |
1200 to_uid, | 1197 to_uid, |
1201 (splay_tree_value)type_map); | 1198 (splay_tree_value)type_map); |
1202 } | 1199 } |
1203 bitmap_set_bit (type_map, TYPE_UID (from_type)); | 1200 bitmap_set_bit (type_map, TYPE_UID (from_type)); |
1204 } | 1201 } |
1205 | 1202 |
1206 /* Scan tree T to see if there are any addresses taken in within T. */ | 1203 /* Scan tree T to see if there are any addresses taken in within T. */ |
1207 | 1204 |
1208 static void | 1205 static void |
1209 look_for_address_of (tree t) | 1206 look_for_address_of (tree t) |
1210 { | 1207 { |
1211 if (TREE_CODE (t) == ADDR_EXPR) | 1208 if (TREE_CODE (t) == ADDR_EXPR) |
1212 { | 1209 { |
1213 tree x = get_base_var (t); | 1210 tree x = get_base_var (t); |
1214 tree cref = TREE_OPERAND (t, 0); | 1211 tree cref = TREE_OPERAND (t, 0); |
1215 | 1212 |
1216 /* If we have an expression of the form "&a.b.c.d", mark a.b, | 1213 /* If we have an expression of the form "&a.b.c.d", mark a.b, |
1217 b.c and c.d. as having its address taken. */ | 1214 b.c and c.d. as having its address taken. */ |
1218 tree fielddecl = NULL_TREE; | 1215 tree fielddecl = NULL_TREE; |
1219 while (cref!= x) | 1216 while (cref!= x) |
1220 { | 1217 { |
1221 if (TREE_CODE (cref) == COMPONENT_REF) | 1218 if (TREE_CODE (cref) == COMPONENT_REF) |
1222 { | 1219 { |
1223 fielddecl = TREE_OPERAND (cref, 1); | 1220 fielddecl = TREE_OPERAND (cref, 1); |
1224 mark_interesting_addressof (TREE_TYPE (fielddecl), | 1221 mark_interesting_addressof (TREE_TYPE (fielddecl), |
1225 DECL_FIELD_CONTEXT (fielddecl)); | 1222 DECL_FIELD_CONTEXT (fielddecl)); |
1226 } | 1223 } |
1227 else if (TREE_CODE (cref) == ARRAY_REF) | 1224 else if (TREE_CODE (cref) == ARRAY_REF) |
1228 get_canon_type (TREE_TYPE (cref), false, false); | 1225 get_canon_type (TREE_TYPE (cref), false, false); |
1229 | 1226 |
1230 cref = TREE_OPERAND (cref, 0); | 1227 cref = TREE_OPERAND (cref, 0); |
1231 } | 1228 } |
1232 | 1229 |
1233 if (TREE_CODE (x) == VAR_DECL) | 1230 if (TREE_CODE (x) == VAR_DECL) |
1234 has_proper_scope_for_analysis (x); | 1231 has_proper_scope_for_analysis (x); |
1235 } | 1232 } |
1236 } | 1233 } |
1237 | 1234 |
1238 | 1235 |
1239 /* Scan tree T to see if there are any casts within it. */ | 1236 /* Scan tree T to see if there are any casts within it. */ |
1240 | 1237 |
1241 static unsigned int | 1238 static unsigned int |
1242 look_for_casts (tree t) | 1239 look_for_casts (tree t) |
1243 { | 1240 { |
1244 unsigned int cast = 0; | 1241 unsigned int cast = 0; |
1245 | 1242 |
1246 if (is_gimple_cast (t) || TREE_CODE (t) == VIEW_CONVERT_EXPR) | 1243 if (is_gimple_cast (t) || TREE_CODE (t) == VIEW_CONVERT_EXPR) |
1247 { | 1244 { |
1248 tree castfromvar = TREE_OPERAND (t, 0); | 1245 tree castfromvar = TREE_OPERAND (t, 0); |
1249 cast = cast | check_cast (TREE_TYPE (t), castfromvar); | 1246 cast = cast | check_cast (TREE_TYPE (t), castfromvar); |
1250 } | 1247 } |
1251 else | 1248 else |
1252 while (handled_component_p (t)) | 1249 while (handled_component_p (t)) |
1253 { | 1250 { |
1254 t = TREE_OPERAND (t, 0); | 1251 t = TREE_OPERAND (t, 0); |
1255 if (TREE_CODE (t) == VIEW_CONVERT_EXPR) | 1252 if (TREE_CODE (t) == VIEW_CONVERT_EXPR) |
1256 { | 1253 { |
1265 } | 1262 } |
1266 | 1263 |
1267 if (!cast) | 1264 if (!cast) |
1268 cast = CT_NO_CAST; | 1265 cast = CT_NO_CAST; |
1269 return cast; | 1266 return cast; |
1270 } | 1267 } |
1271 | 1268 |
1272 /* Check to see if T is a read or address of operation on a static var | 1269 /* Check to see if T is a read or address of operation on a static var |
1273 we are interested in analyzing. */ | 1270 we are interested in analyzing. */ |
1274 | 1271 |
1275 static void | 1272 static void |
1303 for (i = 0; i < gimple_asm_noutputs (stmt); i++) | 1300 for (i = 0; i < gimple_asm_noutputs (stmt); i++) |
1304 check_lhs_var (gimple_asm_output_op (stmt, i)); | 1301 check_lhs_var (gimple_asm_output_op (stmt, i)); |
1305 | 1302 |
1306 for (i = 0; i < gimple_asm_ninputs (stmt); i++) | 1303 for (i = 0; i < gimple_asm_ninputs (stmt); i++) |
1307 check_rhs_var (gimple_asm_input_op (stmt, i)); | 1304 check_rhs_var (gimple_asm_input_op (stmt, i)); |
1308 | 1305 |
1309 /* There is no code here to check for asm memory clobbers. The | 1306 /* There is no code here to check for asm memory clobbers. The |
1310 casual maintainer might think that such code would be necessary, | 1307 casual maintainer might think that such code would be necessary, |
1311 but that appears to be wrong. In other parts of the compiler, | 1308 but that appears to be wrong. In other parts of the compiler, |
1312 the asm memory clobbers are assumed to only clobber variables | 1309 the asm memory clobbers are assumed to only clobber variables |
1313 that are addressable. All types with addressable instances are | 1310 that are addressable. All types with addressable instances are |
1328 enum availability avail = AVAIL_NOT_AVAILABLE; | 1325 enum availability avail = AVAIL_NOT_AVAILABLE; |
1329 size_t i; | 1326 size_t i; |
1330 | 1327 |
1331 for (i = 0; i < gimple_call_num_args (call); i++) | 1328 for (i = 0; i < gimple_call_num_args (call); i++) |
1332 check_rhs_var (gimple_call_arg (call, i)); | 1329 check_rhs_var (gimple_call_arg (call, i)); |
1333 | 1330 |
1334 if (callee_t) | 1331 if (callee_t) |
1335 { | 1332 { |
1336 tree arg_type; | 1333 tree arg_type; |
1337 tree last_arg_type = NULL; | 1334 tree last_arg_type = NULL; |
1338 callee = cgraph_node(callee_t); | 1335 callee = cgraph_node(callee_t); |
1339 avail = cgraph_function_body_availability (callee); | 1336 avail = cgraph_function_body_availability (callee); |
1340 | 1337 |
1341 /* Check that there are no implicit casts in the passing of | 1338 /* Check that there are no implicit casts in the passing of |
1342 parameters. */ | 1339 parameters. */ |
1343 if (TYPE_ARG_TYPES (TREE_TYPE (callee_t))) | 1340 if (TYPE_ARG_TYPES (TREE_TYPE (callee_t))) |
1344 { | 1341 { |
1345 for (arg_type = TYPE_ARG_TYPES (TREE_TYPE (callee_t)), i = 0; | 1342 for (arg_type = TYPE_ARG_TYPES (TREE_TYPE (callee_t)), i = 0; |
1350 if (operand) | 1347 if (operand) |
1351 { | 1348 { |
1352 last_arg_type = TREE_VALUE(arg_type); | 1349 last_arg_type = TREE_VALUE(arg_type); |
1353 check_cast (last_arg_type, operand); | 1350 check_cast (last_arg_type, operand); |
1354 } | 1351 } |
1355 else | 1352 else |
1356 /* The code reaches here for some unfortunate | 1353 /* The code reaches here for some unfortunate |
1357 builtin functions that do not have a list of | 1354 builtin functions that do not have a list of |
1358 argument types. */ | 1355 argument types. */ |
1359 break; | 1356 break; |
1360 } | 1357 } |
1361 } | 1358 } |
1362 else | 1359 else |
1363 { | 1360 { |
1364 /* FIXME - According to Geoff Keating, we should never | 1361 /* FIXME - According to Geoff Keating, we should never |
1365 have to do this; the front ends should always process | 1362 have to do this; the front ends should always process |
1366 the arg list from the TYPE_ARG_LIST. */ | 1363 the arg list from the TYPE_ARG_LIST. */ |
1367 for (arg_type = DECL_ARGUMENTS (callee_t), i = 0; | 1364 for (arg_type = DECL_ARGUMENTS (callee_t), i = 0; |
1368 arg_type; | 1365 arg_type; |
1371 tree operand = gimple_call_arg (call, i); | 1368 tree operand = gimple_call_arg (call, i); |
1372 if (operand) | 1369 if (operand) |
1373 { | 1370 { |
1374 last_arg_type = TREE_TYPE (arg_type); | 1371 last_arg_type = TREE_TYPE (arg_type); |
1375 check_cast (last_arg_type, operand); | 1372 check_cast (last_arg_type, operand); |
1376 } | 1373 } |
1377 else | 1374 else |
1378 /* The code reaches here for some unfortunate | 1375 /* The code reaches here for some unfortunate |
1379 builtin functions that do not have a list of | 1376 builtin functions that do not have a list of |
1380 argument types. */ | 1377 argument types. */ |
1381 break; | 1378 break; |
1382 } | 1379 } |
1383 } | 1380 } |
1384 | 1381 |
1385 /* In the case where we have a var_args function, we need to | 1382 /* In the case where we have a var_args function, we need to |
1386 check the remaining parameters against the last argument. */ | 1383 check the remaining parameters against the last argument. */ |
1387 arg_type = last_arg_type; | 1384 arg_type = last_arg_type; |
1388 for ( ; i < gimple_call_num_args (call); i++) | 1385 for ( ; i < gimple_call_num_args (call); i++) |
1389 { | 1386 { |
1390 tree operand = gimple_call_arg (call, i); | 1387 tree operand = gimple_call_arg (call, i); |
1391 if (arg_type) | 1388 if (arg_type) |
1392 check_cast (arg_type, operand); | 1389 check_cast (arg_type, operand); |
1393 else | 1390 else |
1394 { | 1391 { |
1395 /* The code reaches here for some unfortunate | 1392 /* The code reaches here for some unfortunate |
1396 builtin functions that do not have a list of | 1393 builtin functions that do not have a list of |
1397 argument types. Most of these functions have | 1394 argument types. Most of these functions have |
1398 been marked as having their parameters not | 1395 been marked as having their parameters not |
1416 { | 1413 { |
1417 tree operand = gimple_call_arg (call, i); | 1414 tree operand = gimple_call_arg (call, i); |
1418 tree type = get_canon_type (TREE_TYPE (operand), false, false); | 1415 tree type = get_canon_type (TREE_TYPE (operand), false, false); |
1419 mark_interesting_type (type, EXPOSED_PARAMETER); | 1416 mark_interesting_type (type, EXPOSED_PARAMETER); |
1420 } | 1417 } |
1421 | 1418 |
1422 if (callee_t) | 1419 if (callee_t) |
1423 { | 1420 { |
1424 tree type = | 1421 tree type = |
1425 get_canon_type (TREE_TYPE (TREE_TYPE (callee_t)), false, false); | 1422 get_canon_type (TREE_TYPE (TREE_TYPE (callee_t)), false, false); |
1426 mark_interesting_type (type, EXPOSED_PARAMETER); | 1423 mark_interesting_type (type, EXPOSED_PARAMETER); |
1427 } | 1424 } |
1428 } | 1425 } |
1429 } | 1426 } |
1430 | 1427 |
1431 /* CODE is the operation on OP0 and OP1. OP0 is the operand that we | 1428 /* CODE is the operation on OP0 and OP1. OP0 is the operand that we |
1432 *know* is a pointer type. OP1 may be a pointer type. */ | 1429 *know* is a pointer type. OP1 may be a pointer type. */ |
1433 static bool | 1430 static bool |
1434 okay_pointer_operation (enum tree_code code, tree op0, tree op1) | 1431 okay_pointer_operation (enum tree_code code, tree op0, tree op1) |
1435 { | 1432 { |
1436 tree op0type = TYPE_MAIN_VARIANT (TREE_TYPE (op0)); | 1433 tree op0type = TYPE_MAIN_VARIANT (TREE_TYPE (op0)); |
1437 | 1434 |
1438 switch (code) | 1435 switch (code) |
1447 { | 1444 { |
1448 tree base, offset; | 1445 tree base, offset; |
1449 gimple offset_cast_stmt; | 1446 gimple offset_cast_stmt; |
1450 | 1447 |
1451 if (POINTER_TYPE_P (op0type) | 1448 if (POINTER_TYPE_P (op0type) |
1452 && TREE_CODE (op0) == SSA_NAME | 1449 && TREE_CODE (op0) == SSA_NAME |
1453 && TREE_CODE (op1) == SSA_NAME | 1450 && TREE_CODE (op1) == SSA_NAME |
1454 && is_array_access_through_pointer_and_index (code, op0, op1, | 1451 && is_array_access_through_pointer_and_index (code, op0, op1, |
1455 &base, | 1452 &base, |
1456 &offset, | 1453 &offset, |
1457 &offset_cast_stmt)) | 1454 &offset_cast_stmt)) |
1458 return true; | 1455 return true; |
1459 else | 1456 else |
1460 { | 1457 { |
1461 tree size_of_op0_points_to = TYPE_SIZE_UNIT (TREE_TYPE (op0type)); | 1458 tree size_of_op0_points_to = TYPE_SIZE_UNIT (TREE_TYPE (op0type)); |
1462 | 1459 |
1463 if (CONSTANT_CLASS_P (op1) | 1460 if (CONSTANT_CLASS_P (op1) |
1464 && size_of_op0_points_to | 1461 && size_of_op0_points_to |
1465 && multiple_of_p (TREE_TYPE (size_of_op0_points_to), | 1462 && multiple_of_p (TREE_TYPE (size_of_op0_points_to), |
1466 op1, size_of_op0_points_to)) | 1463 op1, size_of_op0_points_to)) |
1467 return true; | 1464 return true; |
1468 | 1465 |
1469 if (CONSTANT_CLASS_P (op0) | 1466 if (CONSTANT_CLASS_P (op0) |
1470 && size_of_op0_points_to | 1467 && size_of_op0_points_to |
1471 && multiple_of_p (TREE_TYPE (size_of_op0_points_to), | 1468 && multiple_of_p (TREE_TYPE (size_of_op0_points_to), |
1472 op0, size_of_op0_points_to)) | 1469 op0, size_of_op0_points_to)) |
1473 return true; | 1470 return true; |
1474 } | 1471 } |
1475 } | 1472 } |
1476 break; | 1473 break; |
1477 default: | 1474 default: |
1478 return false; | 1475 return false; |
1494 /* For the purposes of figuring out what the cast affects */ | 1491 /* For the purposes of figuring out what the cast affects */ |
1495 | 1492 |
1496 /* Next check the operands on the rhs to see if they are ok. */ | 1493 /* Next check the operands on the rhs to see if they are ok. */ |
1497 switch (TREE_CODE_CLASS (gimple_assign_rhs_code (t))) | 1494 switch (TREE_CODE_CLASS (gimple_assign_rhs_code (t))) |
1498 { | 1495 { |
1499 case tcc_binary: | 1496 case tcc_binary: |
1500 { | 1497 { |
1501 tree op0 = gimple_assign_rhs1 (t); | 1498 tree op0 = gimple_assign_rhs1 (t); |
1502 tree type0 = get_canon_type (TREE_TYPE (op0), false, false); | 1499 tree type0 = get_canon_type (TREE_TYPE (op0), false, false); |
1503 tree op1 = gimple_assign_rhs2 (t); | 1500 tree op1 = gimple_assign_rhs2 (t); |
1504 tree type1 = get_canon_type (TREE_TYPE (op1), false, false); | 1501 tree type1 = get_canon_type (TREE_TYPE (op1), false, false); |
1575 interesting. */ | 1572 interesting. */ |
1576 | 1573 |
1577 static void | 1574 static void |
1578 scan_for_refs (gimple t) | 1575 scan_for_refs (gimple t) |
1579 { | 1576 { |
1580 switch (gimple_code (t)) | 1577 switch (gimple_code (t)) |
1581 { | 1578 { |
1582 case GIMPLE_ASSIGN: | 1579 case GIMPLE_ASSIGN: |
1583 check_assign (t); | 1580 check_assign (t); |
1584 break; | 1581 break; |
1585 | 1582 |
1586 case GIMPLE_CALL: | 1583 case GIMPLE_CALL: |
1587 /* If this is a call to malloc, squirrel away the result so we | 1584 /* If this is a call to malloc, squirrel away the result so we |
1588 do mark the resulting cast as being bad. */ | 1585 do mark the resulting cast as being bad. */ |
1589 check_call (t); | 1586 check_call (t); |
1590 break; | 1587 break; |
1591 | 1588 |
1592 case GIMPLE_ASM: | 1589 case GIMPLE_ASM: |
1593 check_asm (t); | 1590 check_asm (t); |
1594 break; | 1591 break; |
1595 | 1592 |
1596 default: | 1593 default: |
1597 break; | 1594 break; |
1598 } | 1595 } |
1599 | 1596 |
1600 return; | 1597 return; |
1601 } | 1598 } |
1602 | 1599 |
1603 | 1600 |
1604 /* The init routine for analyzing global static variable usage. See | 1601 /* The init routine for analyzing global static variable usage. See |
1605 comments at top for description. */ | 1602 comments at top for description. */ |
1606 static void | 1603 static void |
1607 ipa_init (void) | 1604 ipa_init (void) |
1608 { | 1605 { |
1609 bitmap_obstack_initialize (&ipa_obstack); | 1606 bitmap_obstack_initialize (&ipa_obstack); |
1610 global_types_exposed_parameter = BITMAP_ALLOC (&ipa_obstack); | 1607 global_types_exposed_parameter = BITMAP_ALLOC (&ipa_obstack); |
1611 global_types_full_escape = BITMAP_ALLOC (&ipa_obstack); | 1608 global_types_full_escape = BITMAP_ALLOC (&ipa_obstack); |
1612 global_types_seen = BITMAP_ALLOC (&ipa_obstack); | 1609 global_types_seen = BITMAP_ALLOC (&ipa_obstack); |
1630 if any of them contain addressof operations. Note that some of | 1627 if any of them contain addressof operations. Note that some of |
1631 these variables may not even be referenced in the code in this | 1628 these variables may not even be referenced in the code in this |
1632 compilation unit but their right hand sides may contain references | 1629 compilation unit but their right hand sides may contain references |
1633 to variables defined within this unit. */ | 1630 to variables defined within this unit. */ |
1634 | 1631 |
1635 static void | 1632 static void |
1636 analyze_variable (struct varpool_node *vnode) | 1633 analyze_variable (struct varpool_node *vnode) |
1637 { | 1634 { |
1638 tree global = vnode->decl; | 1635 tree global = vnode->decl; |
1639 tree type = get_canon_type (TREE_TYPE (global), false, false); | 1636 tree type = get_canon_type (TREE_TYPE (global), false, false); |
1640 | 1637 |
1655 | 1652 |
1656 static void | 1653 static void |
1657 analyze_function (struct cgraph_node *fn) | 1654 analyze_function (struct cgraph_node *fn) |
1658 { | 1655 { |
1659 tree decl = fn->decl; | 1656 tree decl = fn->decl; |
1660 check_function_parameter_and_return_types (decl, | 1657 check_function_parameter_and_return_types (decl, |
1661 fn->local.externally_visible); | 1658 fn->local.externally_visible); |
1662 if (dump_file) | 1659 if (dump_file) |
1663 fprintf (dump_file, "\n local analysis of %s", cgraph_node_name (fn)); | 1660 fprintf (dump_file, "\n local analysis of %s", cgraph_node_name (fn)); |
1664 | 1661 |
1665 { | 1662 { |
1666 struct function *this_cfun = DECL_STRUCT_FUNCTION (decl); | 1663 struct function *this_cfun = DECL_STRUCT_FUNCTION (decl); |
1667 basic_block this_block; | 1664 basic_block this_block; |
1668 | 1665 |
1669 FOR_EACH_BB_FN (this_block, this_cfun) | 1666 FOR_EACH_BB_FN (this_block, this_cfun) |
1681 for (step = DECL_STRUCT_FUNCTION (decl)->local_decls; | 1678 for (step = DECL_STRUCT_FUNCTION (decl)->local_decls; |
1682 step; | 1679 step; |
1683 step = TREE_CHAIN (step)) | 1680 step = TREE_CHAIN (step)) |
1684 { | 1681 { |
1685 tree var = TREE_VALUE (step); | 1682 tree var = TREE_VALUE (step); |
1686 if (TREE_CODE (var) == VAR_DECL | 1683 if (TREE_CODE (var) == VAR_DECL |
1687 && DECL_INITIAL (var) | 1684 && DECL_INITIAL (var) |
1688 && !TREE_STATIC (var)) | 1685 && !TREE_STATIC (var)) |
1689 check_tree (DECL_INITIAL (var)); | 1686 check_tree (DECL_INITIAL (var)); |
1690 get_canon_type (TREE_TYPE (var), false, false); | 1687 get_canon_type (TREE_TYPE (var), false, false); |
1691 } | 1688 } |
1696 | 1693 |
1697 /* Convert a type_UID into a type. */ | 1694 /* Convert a type_UID into a type. */ |
1698 static tree | 1695 static tree |
1699 type_for_uid (int uid) | 1696 type_for_uid (int uid) |
1700 { | 1697 { |
1701 splay_tree_node result = | 1698 splay_tree_node result = |
1702 splay_tree_lookup (uid_to_canon_type, (splay_tree_key) uid); | 1699 splay_tree_lookup (uid_to_canon_type, (splay_tree_key) uid); |
1703 | 1700 |
1704 if (result) | 1701 if (result) |
1705 return (tree) result->value; | 1702 return (tree) result->value; |
1706 else return NULL; | 1703 else return NULL; |
1707 } | 1704 } |
1708 | 1705 |
1709 /* Return a bitmap with the subtypes of the type for UID. If it | 1706 /* Return a bitmap with the subtypes of the type for UID. If it |
1710 does not exist, return either NULL or a new bitmap depending on the | 1707 does not exist, return either NULL or a new bitmap depending on the |
1711 value of CREATE. */ | 1708 value of CREATE. */ |
1712 | 1709 |
1713 static bitmap | 1710 static bitmap |
1714 subtype_map_for_uid (int uid, bool create) | 1711 subtype_map_for_uid (int uid, bool create) |
1715 { | 1712 { |
1716 splay_tree_node result = splay_tree_lookup (uid_to_subtype_map, | 1713 splay_tree_node result = splay_tree_lookup (uid_to_subtype_map, |
1717 (splay_tree_key) uid); | 1714 (splay_tree_key) uid); |
1718 | 1715 |
1719 if (result) | 1716 if (result) |
1720 return (bitmap) result->value; | 1717 return (bitmap) result->value; |
1721 else if (create) | 1718 else if (create) |
1722 { | 1719 { |
1723 bitmap subtype_map = BITMAP_ALLOC (&ipa_obstack); | 1720 bitmap subtype_map = BITMAP_ALLOC (&ipa_obstack); |
1724 splay_tree_insert (uid_to_subtype_map, | 1721 splay_tree_insert (uid_to_subtype_map, |
1725 uid, | 1722 uid, |
1726 (splay_tree_value)subtype_map); | 1723 (splay_tree_value)subtype_map); |
1727 return subtype_map; | 1724 return subtype_map; |
1728 } | 1725 } |
1729 else return NULL; | 1726 else return NULL; |
1730 } | 1727 } |
1752 return; | 1749 return; |
1753 bitmap_set_bit (been_there_done_that, uid); | 1750 bitmap_set_bit (been_there_done_that, uid); |
1754 | 1751 |
1755 /* If we are doing a language with a type hierarchy, mark all of | 1752 /* If we are doing a language with a type hierarchy, mark all of |
1756 the superclasses. */ | 1753 the superclasses. */ |
1757 if (TYPE_BINFO (type)) | 1754 if (TYPE_BINFO (type)) |
1758 for (binfo = TYPE_BINFO (type), i = 0; | 1755 for (binfo = TYPE_BINFO (type), i = 0; |
1759 BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) | 1756 BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) |
1760 { | 1757 { |
1761 tree binfo_type = BINFO_TYPE (base_binfo); | 1758 tree binfo_type = BINFO_TYPE (base_binfo); |
1762 bitmap subtype_map = subtype_map_for_uid | 1759 bitmap subtype_map = subtype_map_for_uid |
1763 (TYPE_UID (TYPE_MAIN_VARIANT (binfo_type)), true); | 1760 (TYPE_UID (TYPE_MAIN_VARIANT (binfo_type)), true); |
1764 bitmap_set_bit (subtype_map, uid); | 1761 bitmap_set_bit (subtype_map, uid); |
1765 close_type_seen (get_canon_type (binfo_type, true, true)); | 1762 close_type_seen (get_canon_type (binfo_type, true, true)); |
1766 } | 1763 } |
1767 | 1764 |
1768 /* If the field is a struct or union type, mark all of the | 1765 /* If the field is a struct or union type, mark all of the |
1769 subfields. */ | 1766 subfields. */ |
1770 for (field = TYPE_FIELDS (type); | 1767 for (field = TYPE_FIELDS (type); |
1771 field; | 1768 field; |
1772 field = TREE_CHAIN (field)) | 1769 field = TREE_CHAIN (field)) |
1782 } | 1779 } |
1783 | 1780 |
1784 /* Take a TYPE that has been passed by value to an external function | 1781 /* Take a TYPE that has been passed by value to an external function |
1785 and mark all of the fields that have pointer types as escaping. For | 1782 and mark all of the fields that have pointer types as escaping. For |
1786 any of the non pointer types that are structures or unions, | 1783 any of the non pointer types that are structures or unions, |
1787 recurse. TYPE is never a pointer type. */ | 1784 recurse. TYPE is never a pointer type. */ |
1788 | 1785 |
1789 static void | 1786 static void |
1790 close_type_exposed_parameter (tree type) | 1787 close_type_exposed_parameter (tree type) |
1791 { | 1788 { |
1792 tree field; | 1789 tree field; |
1815 | 1812 |
1816 field_type = get_canon_type (TREE_TYPE (field), false, false); | 1813 field_type = get_canon_type (TREE_TYPE (field), false, false); |
1817 mark_interesting_type (field_type, EXPOSED_PARAMETER); | 1814 mark_interesting_type (field_type, EXPOSED_PARAMETER); |
1818 | 1815 |
1819 /* Only recurse for non pointer types of structures and unions. */ | 1816 /* Only recurse for non pointer types of structures and unions. */ |
1820 if (ipa_type_escape_star_count_of_interesting_type (field_type) == 0) | 1817 if (ipa_type_escape_star_count_of_interesting_type (field_type) == 0) |
1821 close_type_exposed_parameter (field_type); | 1818 close_type_exposed_parameter (field_type); |
1822 } | 1819 } |
1823 } | 1820 } |
1824 | 1821 |
1825 /* The next function handles the case where a type fully escapes. | 1822 /* The next function handles the case where a type fully escapes. |
1826 This means that not only does the type itself escape, | 1823 This means that not only does the type itself escape, |
1827 | 1824 |
1828 a) the type of every field recursively escapes | 1825 a) the type of every field recursively escapes |
1829 b) the type of every subtype escapes as well as the super as well | 1826 b) the type of every subtype escapes as well as the super as well |
1830 as all of the pointer to types for each field. | 1827 as all of the pointer to types for each field. |
1831 | 1828 |
1832 Note that pointer to types are not marked as escaping. If the | 1829 Note that pointer to types are not marked as escaping. If the |
1833 pointed to type escapes, the pointer to type also escapes. | 1830 pointed to type escapes, the pointer to type also escapes. |
1834 | 1831 |
1835 Take a TYPE that has had the address taken for an instance of it | 1832 Take a TYPE that has had the address taken for an instance of it |
1836 and mark all of the types for its fields as having their addresses | 1833 and mark all of the types for its fields as having their addresses |
1837 taken. */ | 1834 taken. */ |
1838 | 1835 |
1839 static void | 1836 static void |
1840 close_type_full_escape (tree type) | 1837 close_type_full_escape (tree type) |
1841 { | 1838 { |
1842 tree field; | 1839 tree field; |
1843 unsigned int i; | 1840 unsigned int i; |
1844 int uid; | 1841 int uid; |
1845 tree binfo, base_binfo; | 1842 tree binfo, base_binfo; |
1846 bitmap_iterator bi; | 1843 bitmap_iterator bi; |
1847 bitmap subtype_map; | 1844 bitmap subtype_map; |
1848 splay_tree_node address_result; | 1845 splay_tree_node address_result; |
1849 | 1846 |
1850 /* Strip off any pointer or array types. */ | 1847 /* Strip off any pointer or array types. */ |
1851 type = get_canon_type (type, true, true); | 1848 type = get_canon_type (type, true, true); |
1852 if (!type) | 1849 if (!type) |
1853 return; | 1850 return; |
1859 | 1856 |
1860 subtype_map = subtype_map_for_uid (uid, false); | 1857 subtype_map = subtype_map_for_uid (uid, false); |
1861 | 1858 |
1862 /* If we are doing a language with a type hierarchy, mark all of | 1859 /* If we are doing a language with a type hierarchy, mark all of |
1863 the superclasses. */ | 1860 the superclasses. */ |
1864 if (TYPE_BINFO (type)) | 1861 if (TYPE_BINFO (type)) |
1865 for (binfo = TYPE_BINFO (type), i = 0; | 1862 for (binfo = TYPE_BINFO (type), i = 0; |
1866 BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) | 1863 BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) |
1867 { | 1864 { |
1868 tree binfotype = BINFO_TYPE (base_binfo); | 1865 tree binfotype = BINFO_TYPE (base_binfo); |
1869 binfotype = mark_type (binfotype, FULL_ESCAPE); | 1866 binfotype = mark_type (binfotype, FULL_ESCAPE); |
1870 close_type_full_escape (binfotype); | 1867 close_type_full_escape (binfotype); |
1871 } | 1868 } |
1872 | 1869 |
1873 /* Mark as escaped any types that have been down casted to | 1870 /* Mark as escaped any types that have been down casted to |
1874 this type. */ | 1871 this type. */ |
1875 if (subtype_map) | 1872 if (subtype_map) |
1876 EXECUTE_IF_SET_IN_BITMAP (subtype_map, 0, i, bi) | 1873 EXECUTE_IF_SET_IN_BITMAP (subtype_map, 0, i, bi) |
1877 { | 1874 { |
1878 tree subtype = type_for_uid (i); | 1875 tree subtype = type_for_uid (i); |
1879 subtype = mark_type (subtype, FULL_ESCAPE); | 1876 subtype = mark_type (subtype, FULL_ESCAPE); |
1880 close_type_full_escape (subtype); | 1877 close_type_full_escape (subtype); |
1881 } | 1878 } |
1882 | 1879 |
1883 /* If the field is a struct or union type, mark all of the | 1880 /* If the field is a struct or union type, mark all of the |
1898 } | 1895 } |
1899 } | 1896 } |
1900 | 1897 |
1901 /* For all of the types A that contain this type B and were part of | 1898 /* For all of the types A that contain this type B and were part of |
1902 an expression like "&...A.B...", mark the A's as escaping. */ | 1899 an expression like "&...A.B...", mark the A's as escaping. */ |
1903 address_result = splay_tree_lookup (uid_to_addressof_up_map, | 1900 address_result = splay_tree_lookup (uid_to_addressof_up_map, |
1904 (splay_tree_key) uid); | 1901 (splay_tree_key) uid); |
1905 if (address_result) | 1902 if (address_result) |
1906 { | 1903 { |
1907 bitmap containing_classes = (bitmap) address_result->value; | 1904 bitmap containing_classes = (bitmap) address_result->value; |
1908 EXECUTE_IF_SET_IN_BITMAP (containing_classes, 0, i, bi) | 1905 EXECUTE_IF_SET_IN_BITMAP (containing_classes, 0, i, bi) |
1912 } | 1909 } |
1913 } | 1910 } |
1914 | 1911 |
1915 /* Transitively close the addressof bitmap for the type with UID. | 1912 /* Transitively close the addressof bitmap for the type with UID. |
1916 This means that if we had a.b and b.c, a would have both b and c in | 1913 This means that if we had a.b and b.c, a would have both b and c in |
1917 its maps. */ | 1914 its maps. */ |
1918 | 1915 |
1919 static bitmap | 1916 static bitmap |
1920 close_addressof_down (int uid) | 1917 close_addressof_down (int uid) |
1921 { | 1918 { |
1922 bitmap_iterator bi; | 1919 bitmap_iterator bi; |
1923 splay_tree_node result = | 1920 splay_tree_node result = |
1924 splay_tree_lookup (uid_to_addressof_down_map, (splay_tree_key) uid); | 1921 splay_tree_lookup (uid_to_addressof_down_map, (splay_tree_key) uid); |
1925 bitmap map = NULL; | 1922 bitmap map = NULL; |
1926 bitmap new_map; | 1923 bitmap new_map; |
1927 unsigned int i; | 1924 unsigned int i; |
1928 | 1925 |
1929 if (result) | 1926 if (result) |
1930 map = (bitmap) result->value; | 1927 map = (bitmap) result->value; |
1931 else | 1928 else |
1932 return NULL; | 1929 return NULL; |
1933 | 1930 |
1934 if (bitmap_bit_p (been_there_done_that, uid)) | 1931 if (bitmap_bit_p (been_there_done_that, uid)) |
1935 return map; | 1932 return map; |
1936 bitmap_set_bit (been_there_done_that, uid); | 1933 bitmap_set_bit (been_there_done_that, uid); |
1950 | 1947 |
1951 EXECUTE_IF_SET_IN_BITMAP (map, 0, i, bi) | 1948 EXECUTE_IF_SET_IN_BITMAP (map, 0, i, bi) |
1952 { | 1949 { |
1953 bitmap submap = close_addressof_down (i); | 1950 bitmap submap = close_addressof_down (i); |
1954 bitmap_set_bit (new_map, i); | 1951 bitmap_set_bit (new_map, i); |
1955 if (submap) | 1952 if (submap) |
1956 bitmap_ior_into (new_map, submap); | 1953 bitmap_ior_into (new_map, submap); |
1957 } | 1954 } |
1958 result->value = (splay_tree_value) new_map; | 1955 result->value = (splay_tree_value) new_map; |
1959 | 1956 |
1960 BITMAP_FREE (map); | 1957 BITMAP_FREE (map); |
1961 return new_map; | 1958 return new_map; |
1962 } | 1959 } |
1982 /* Process all of the functions next. | 1979 /* Process all of the functions next. |
1983 | 1980 |
1984 We do not want to process any of the clones so we check that this | 1981 We do not want to process any of the clones so we check that this |
1985 is a master clone. However, we do need to process any | 1982 is a master clone. However, we do need to process any |
1986 AVAIL_OVERWRITABLE functions (these are never clones) because | 1983 AVAIL_OVERWRITABLE functions (these are never clones) because |
1987 they may cause a type variable to escape. | 1984 they may cause a type variable to escape. |
1988 */ | 1985 */ |
1989 for (node = cgraph_nodes; node; node = node->next) | 1986 for (node = cgraph_nodes; node; node = node->next) |
1990 if (node->analyzed | 1987 if (node->analyzed) |
1991 && (cgraph_is_master_clone (node) | |
1992 || (cgraph_function_body_availability (node) == AVAIL_OVERWRITABLE))) | |
1993 analyze_function (node); | 1988 analyze_function (node); |
1994 | 1989 |
1995 | 1990 |
1996 pointer_set_destroy (visited_nodes); | 1991 pointer_set_destroy (visited_nodes); |
1997 visited_nodes = NULL; | 1992 visited_nodes = NULL; |
2035 | 2030 |
2036 /* Before this pass, the uid_to_addressof_down_map for type X | 2031 /* Before this pass, the uid_to_addressof_down_map for type X |
2037 contained an entry for Y if there had been an operation of the | 2032 contained an entry for Y if there had been an operation of the |
2038 form &X.Y. This step adds all of the fields contained within Y | 2033 form &X.Y. This step adds all of the fields contained within Y |
2039 (recursively) to X's map. */ | 2034 (recursively) to X's map. */ |
2040 | 2035 |
2041 result = splay_tree_min (uid_to_addressof_down_map); | 2036 result = splay_tree_min (uid_to_addressof_down_map); |
2042 while (result) | 2037 while (result) |
2043 { | 2038 { |
2044 int uid = result->key; | 2039 int uid = result->key; |
2045 /* Close the addressof map, i.e. copy all of the transitive | 2040 /* Close the addressof map, i.e. copy all of the transitive |
2053 result = splay_tree_min (all_canon_types); | 2048 result = splay_tree_min (all_canon_types); |
2054 while (result) | 2049 while (result) |
2055 { | 2050 { |
2056 tree type = (tree) result->value; | 2051 tree type = (tree) result->value; |
2057 tree key = (tree) result->key; | 2052 tree key = (tree) result->key; |
2058 if (POINTER_TYPE_P (type) | 2053 if (POINTER_TYPE_P (type) |
2059 || TREE_CODE (type) == ARRAY_TYPE) | 2054 || TREE_CODE (type) == ARRAY_TYPE) |
2060 { | 2055 { |
2061 splay_tree_remove (all_canon_types, (splay_tree_key) result->key); | 2056 splay_tree_remove (all_canon_types, (splay_tree_key) result->key); |
2062 splay_tree_remove (type_to_canon_type, (splay_tree_key) type); | 2057 splay_tree_remove (type_to_canon_type, (splay_tree_key) type); |
2063 splay_tree_remove (uid_to_canon_type, (splay_tree_key) TYPE_UID (type)); | 2058 splay_tree_remove (uid_to_canon_type, (splay_tree_key) TYPE_UID (type)); |
2065 } | 2060 } |
2066 result = splay_tree_successor (all_canon_types, (splay_tree_key) key); | 2061 result = splay_tree_successor (all_canon_types, (splay_tree_key) key); |
2067 } | 2062 } |
2068 | 2063 |
2069 if (dump_file) | 2064 if (dump_file) |
2070 { | 2065 { |
2071 EXECUTE_IF_SET_IN_BITMAP (global_types_seen, 0, i, bi) | 2066 EXECUTE_IF_SET_IN_BITMAP (global_types_seen, 0, i, bi) |
2072 { | 2067 { |
2073 /* The pointer types are in the global_types_full_escape | 2068 /* The pointer types are in the global_types_full_escape |
2074 bitmap but not in the backwards map. They also contain | 2069 bitmap but not in the backwards map. They also contain |
2075 no useful information since they are not marked. */ | 2070 no useful information since they are not marked. */ |
2076 tree type = type_for_uid (i); | 2071 tree type = type_for_uid (i); |
2077 fprintf(dump_file, "type %d ", i); | 2072 fprintf(dump_file, "type %d ", i); |
2078 print_generic_expr (dump_file, type, 0); | 2073 print_generic_expr (dump_file, type, 0); |
2079 if (bitmap_bit_p (global_types_full_escape, i)) | 2074 if (bitmap_bit_p (global_types_full_escape, i)) |
2080 fprintf(dump_file, " escaped\n"); | 2075 fprintf(dump_file, " escaped\n"); |
2081 else | 2076 else |
2082 fprintf(dump_file, " contained\n"); | 2077 fprintf(dump_file, " contained\n"); |
2083 } | 2078 } |
2084 } | 2079 } |
2085 | 2080 |
2086 /* Get rid of uid_to_addressof_up_map and its bitmaps. */ | 2081 /* Get rid of uid_to_addressof_up_map and its bitmaps. */ |