00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "config.h"
00037 #include "system.h"
00038 #include "coretypes.h"
00039 #include "tm.h"
00040 #include "tree.h"
00041 #include "tree-flow.h"
00042 #include "tree-inline.h"
00043 #include "tree-pass.h"
00044 #include "langhooks.h"
00045 #include "pointer-set.h"
00046 #include "ggc.h"
00047 #include "ipa-utils.h"
00048 #include "ipa-type-escape.h"
00049 #include "c-common.h"
00050 #include "tree-gimple.h"
00051 #include "cgraph.h"
00052 #include "output.h"
00053 #include "flags.h"
00054 #include "timevar.h"
00055 #include "diagnostic.h"
00056 #include "langhooks.h"
00057
00058
00059
00060
00061 static bool initialized = false;
00062
00063
00064
00065
00066
00067
00068 static bitmap results_of_malloc;
00069
00070
00071 static bitmap been_there_done_that;
00072 static bitmap bitmap_tmp;
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 enum escape_t
00091 {
00092 EXPOSED_PARAMETER,
00093 FULL_ESCAPE
00094 };
00095
00096
00097
00098
00099
00100
00101 static bitmap global_types_exposed_parameter;
00102 static bitmap global_types_full_escape;
00103
00104
00105 static bitmap global_types_seen;
00106
00107
00108
00109 static splay_tree uid_to_canon_type;
00110
00111
00112
00113 static splay_tree all_canon_types;
00114
00115
00116 static splay_tree type_to_canon_type;
00117
00118
00119
00120
00121 static splay_tree uid_to_addressof_down_map;
00122
00123
00124
00125
00126 static splay_tree uid_to_addressof_up_map;
00127
00128
00129
00130 static splay_tree uid_to_subtype_map;
00131
00132
00133
00134
00135
00136 static struct pointer_set_t *visited_nodes;
00137
00138 static bitmap_obstack ipa_obstack;
00139
00140
00141 static char*
00142 get_name_of_type (tree type)
00143 {
00144 tree name = TYPE_NAME (type);
00145
00146 if (!name)
00147
00148 return (char*)"<UNNAMED>";
00149
00150
00151
00152 if (TREE_CODE (name) == TYPE_DECL)
00153 {
00154
00155
00156
00157 if (DECL_NAME (name))
00158 return (char*)IDENTIFIER_POINTER (DECL_NAME (name));
00159 else
00160
00161 return (char*)"<UNNAMED>";
00162 }
00163 else if (TREE_CODE (name) == IDENTIFIER_NODE)
00164 return (char*)IDENTIFIER_POINTER (name);
00165 else
00166 return (char*)"<UNNAMED>";
00167 }
00168
00169 struct type_brand_s
00170 {
00171 char* name;
00172 int seq;
00173 };
00174
00175
00176
00177 static int
00178 compare_type_brand (splay_tree_key sk1, splay_tree_key sk2)
00179 {
00180 struct type_brand_s * k1 = (struct type_brand_s *) sk1;
00181 struct type_brand_s * k2 = (struct type_brand_s *) sk2;
00182
00183 int value = strcmp(k1->name, k2->name);
00184 if (value == 0)
00185 return k2->seq - k1->seq;
00186 else
00187 return value;
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 static tree
00201 discover_unique_type (tree type)
00202 {
00203 struct type_brand_s * brand = XNEW (struct type_brand_s);
00204 int i = 0;
00205 splay_tree_node result;
00206
00207 brand->name = get_name_of_type (type);
00208
00209 while (1)
00210 {
00211 brand->seq = i++;
00212 result = splay_tree_lookup (all_canon_types, (splay_tree_key) brand);
00213
00214 if (result)
00215 {
00216
00217
00218 tree other_type = (tree) result->value;
00219 if (lang_hooks.types_compatible_p (type, other_type) == 1)
00220 {
00221 free (brand);
00222
00223 splay_tree_insert (type_to_canon_type,
00224 (splay_tree_key) type,
00225 (splay_tree_value) other_type);
00226 return other_type;
00227 }
00228
00229 }
00230 else
00231 {
00232
00233
00234 brand->seq = i++;
00235
00236 splay_tree_insert (all_canon_types,
00237 (splay_tree_key) brand,
00238 (splay_tree_value) type);
00239
00240
00241 splay_tree_insert (type_to_canon_type,
00242 (splay_tree_key) type,
00243 (splay_tree_value) type);
00244
00245
00246 splay_tree_insert (uid_to_canon_type,
00247 (splay_tree_key) TYPE_UID (type),
00248 (splay_tree_value) type);
00249
00250 bitmap_set_bit (global_types_seen, TYPE_UID (type));
00251 return type;
00252 }
00253 }
00254 }
00255
00256
00257
00258
00259 static bool
00260 type_to_consider (tree type)
00261 {
00262
00263 type = TYPE_MAIN_VARIANT (type);
00264 while (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
00265 type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
00266
00267 switch (TREE_CODE (type))
00268 {
00269 case BOOLEAN_TYPE:
00270 case COMPLEX_TYPE:
00271 case ENUMERAL_TYPE:
00272 case INTEGER_TYPE:
00273 case QUAL_UNION_TYPE:
00274 case REAL_TYPE:
00275 case RECORD_TYPE:
00276 case UNION_TYPE:
00277 case VECTOR_TYPE:
00278 case VOID_TYPE:
00279 return true;
00280
00281 default:
00282 return false;
00283 }
00284 }
00285
00286
00287
00288
00289
00290 static tree
00291 get_canon_type (tree type, bool see_thru_ptrs, bool see_thru_arrays)
00292 {
00293 splay_tree_node result;
00294
00295 if (!type || !type_to_consider (type))
00296 return NULL;
00297
00298 type = TYPE_MAIN_VARIANT (type);
00299 if (see_thru_arrays)
00300 while (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
00301 type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
00302
00303 else if (see_thru_ptrs)
00304 while (POINTER_TYPE_P (type))
00305 type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
00306
00307 result = splay_tree_lookup(type_to_canon_type, (splay_tree_key) type);
00308
00309 if (result == NULL)
00310 return discover_unique_type (type);
00311 else return (tree) result->value;
00312 }
00313
00314
00315
00316
00317 static int
00318 get_canon_type_uid (tree type, bool see_thru_ptrs, bool see_thru_arrays)
00319 {
00320 type = get_canon_type (type, see_thru_ptrs, see_thru_arrays);
00321 if (type)
00322 return TYPE_UID(type);
00323 else return 0;
00324 }
00325
00326
00327
00328
00329
00330
00331 int
00332 ipa_type_escape_star_count_of_interesting_type (tree type)
00333 {
00334 int count = 0;
00335
00336 if (!type)
00337 return -1;
00338 type = TYPE_MAIN_VARIANT (type);
00339 while (POINTER_TYPE_P (type))
00340 {
00341 type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
00342 count++;
00343 }
00344
00345
00346 if (TREE_CODE (type) == RECORD_TYPE
00347 || TREE_CODE (type) == QUAL_UNION_TYPE
00348 || TREE_CODE (type) == UNION_TYPE)
00349 return count;
00350 else
00351 return -1;
00352 }
00353
00354
00355
00356
00357
00358
00359
00360 int
00361 ipa_type_escape_star_count_of_interesting_or_array_type (tree type)
00362 {
00363 int count = 0;
00364
00365 if (!type)
00366 return -1;
00367 type = TYPE_MAIN_VARIANT (type);
00368 while (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
00369 {
00370 type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
00371 count++;
00372 }
00373
00374
00375 if (TREE_CODE (type) == RECORD_TYPE
00376 || TREE_CODE (type) == QUAL_UNION_TYPE
00377 || TREE_CODE (type) == UNION_TYPE)
00378 return count;
00379 else
00380 return -1;
00381 }
00382
00383
00384
00385
00386
00387
00388 bool
00389 ipa_type_escape_type_contained_p (tree type)
00390 {
00391 if (!initialized)
00392 return false;
00393 return !bitmap_bit_p (global_types_full_escape,
00394 get_canon_type_uid (type, true, false));
00395 }
00396
00397
00398
00399
00400 bool
00401 ipa_type_escape_field_does_not_clobber_p (tree record_type, tree field_type)
00402 {
00403 splay_tree_node result;
00404 int uid;
00405
00406 if (!initialized)
00407 return false;
00408
00409
00410
00411
00412 record_type = TYPE_MAIN_VARIANT (record_type);
00413 field_type = TYPE_MAIN_VARIANT (field_type);
00414 while (POINTER_TYPE_P (record_type))
00415 {
00416 record_type = TYPE_MAIN_VARIANT (TREE_TYPE (record_type));
00417 if (POINTER_TYPE_P (field_type))
00418 field_type = TYPE_MAIN_VARIANT (TREE_TYPE (field_type));
00419 else
00420
00421
00422
00423
00424
00425 if (TREE_CODE (field_type) == QUAL_UNION_TYPE
00426 || TREE_CODE (field_type) == UNION_TYPE)
00427 {
00428 while (POINTER_TYPE_P (record_type))
00429 record_type = TYPE_MAIN_VARIANT (TREE_TYPE (record_type));
00430 break;
00431 }
00432 else
00433 return true;
00434 }
00435
00436 record_type = get_canon_type (record_type, true, true);
00437
00438
00439 if (!ipa_type_escape_type_contained_p (record_type))
00440 return false;
00441
00442 uid = TYPE_UID (record_type);
00443 result = splay_tree_lookup (uid_to_addressof_down_map, (splay_tree_key) uid);
00444
00445 if (result)
00446 {
00447 bitmap field_type_map = (bitmap) result->value;
00448 uid = get_canon_type_uid (field_type, true, true);
00449
00450
00451 return !bitmap_bit_p (field_type_map, uid);
00452 }
00453 else
00454
00455 return true;
00456 }
00457
00458
00459
00460
00461
00462 static tree
00463 mark_type (tree type, enum escape_t escape_status)
00464 {
00465 bitmap map = NULL;
00466 int uid;
00467
00468 type = get_canon_type (type, true, true);
00469 if (!type)
00470 return NULL;
00471
00472 switch (escape_status)
00473 {
00474 case EXPOSED_PARAMETER:
00475 map = global_types_exposed_parameter;
00476 break;
00477 case FULL_ESCAPE:
00478 map = global_types_full_escape;
00479 break;
00480 }
00481
00482 uid = TYPE_UID (type);
00483 if (bitmap_bit_p (map, uid))
00484 return type;
00485 else
00486 {
00487 bitmap_set_bit (map, uid);
00488 if (escape_status == FULL_ESCAPE)
00489 {
00490
00491
00492 bitmap_set_bit (global_types_exposed_parameter, uid);
00493 }
00494 }
00495 return type;
00496 }
00497
00498
00499
00500
00501
00502 static void
00503 mark_interesting_type (tree type, enum escape_t escape_status)
00504 {
00505 if (!type) return;
00506 if (ipa_type_escape_star_count_of_interesting_type (type) >= 0)
00507 {
00508 if ((escape_status == EXPOSED_PARAMETER)
00509 && POINTER_TYPE_P (type))
00510
00511
00512
00513 mark_type (type, FULL_ESCAPE);
00514 else
00515 mark_type (type, escape_status);
00516 }
00517 }
00518
00519
00520
00521
00522 static bool
00523 parent_type_p (tree parent, tree child)
00524 {
00525 int i;
00526 tree binfo, base_binfo;
00527 if (TYPE_BINFO (parent))
00528 for (binfo = TYPE_BINFO (parent), i = 0;
00529 BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
00530 {
00531 tree binfotype = BINFO_TYPE (base_binfo);
00532 if (binfotype == child)
00533 return true;
00534 else if (parent_type_p (binfotype, child))
00535 return true;
00536 }
00537 if (TREE_CODE (parent) == UNION_TYPE
00538 || TREE_CODE (parent) == QUAL_UNION_TYPE)
00539 {
00540 tree field;
00541
00542
00543 for (field = TYPE_FIELDS (parent);
00544 field;
00545 field = TREE_CHAIN (field))
00546 {
00547 tree field_type;
00548 if (TREE_CODE (field) != FIELD_DECL)
00549 continue;
00550
00551 field_type = TREE_TYPE (field);
00552 if (field_type == child)
00553 return true;
00554 }
00555
00556
00557
00558 for (field = TYPE_FIELDS (parent);
00559 field;
00560 field = TREE_CHAIN (field))
00561 {
00562 tree field_type;
00563 if (TREE_CODE (field) != FIELD_DECL)
00564 continue;
00565
00566 field_type = TREE_TYPE (field);
00567 if (TREE_CODE (field_type) == RECORD_TYPE
00568 || TREE_CODE (field_type) == QUAL_UNION_TYPE
00569 || TREE_CODE (field_type) == UNION_TYPE)
00570 if (parent_type_p (field_type, child))
00571 return true;
00572 }
00573 }
00574
00575 if (TREE_CODE (parent) == RECORD_TYPE)
00576 {
00577 tree field;
00578 for (field = TYPE_FIELDS (parent);
00579 field;
00580 field = TREE_CHAIN (field))
00581 {
00582 tree field_type;
00583 if (TREE_CODE (field) != FIELD_DECL)
00584 continue;
00585
00586 field_type = TREE_TYPE (field);
00587 if (field_type == child)
00588 return true;
00589
00590
00591 if (TREE_CODE (field_type) == RECORD_TYPE
00592 || TREE_CODE (field_type) == QUAL_UNION_TYPE
00593 || TREE_CODE (field_type) == UNION_TYPE)
00594 {
00595 if (parent_type_p (field_type, child))
00596 return true;
00597 else
00598 break;
00599 }
00600 }
00601 }
00602 return false;
00603 }
00604
00605
00606
00607
00608 static int
00609 count_stars (tree* type_ptr)
00610 {
00611 tree type = *type_ptr;
00612 int i = 0;
00613 type = TYPE_MAIN_VARIANT (type);
00614 while (POINTER_TYPE_P (type))
00615 {
00616 type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
00617 i++;
00618 }
00619
00620 *type_ptr = type;
00621 return i;
00622 }
00623
00624 enum cast_type {
00625 CT_UP,
00626 CT_DOWN,
00627 CT_SIDEWAYS,
00628 CT_USELESS
00629 };
00630
00631
00632
00633
00634
00635 static enum cast_type
00636 check_cast_type (tree to_type, tree from_type)
00637 {
00638 int to_stars = count_stars (&to_type);
00639 int from_stars = count_stars (&from_type);
00640 if (to_stars != from_stars)
00641 return CT_SIDEWAYS;
00642
00643 if (to_type == from_type)
00644 return CT_USELESS;
00645
00646 if (parent_type_p (to_type, from_type)) return CT_UP;
00647 if (parent_type_p (from_type, to_type)) return CT_DOWN;
00648 return CT_SIDEWAYS;
00649 }
00650
00651
00652
00653 static void
00654 check_cast (tree to_type, tree from)
00655 {
00656 tree from_type = get_canon_type (TREE_TYPE (from), false, false);
00657 bool to_interesting_type, from_interesting_type;
00658
00659 to_type = get_canon_type (to_type, false, false);
00660 if (!from_type || !to_type || from_type == to_type)
00661 return;
00662
00663 to_interesting_type =
00664 ipa_type_escape_star_count_of_interesting_type (to_type) >= 0;
00665 from_interesting_type =
00666 ipa_type_escape_star_count_of_interesting_type (from_type) >= 0;
00667
00668 if (to_interesting_type)
00669 if (from_interesting_type)
00670 {
00671
00672
00673
00674
00675
00676
00677 switch (check_cast_type (to_type, from_type))
00678 {
00679 case CT_UP:
00680 case CT_USELESS:
00681 case CT_DOWN:
00682 break;
00683
00684 case CT_SIDEWAYS:
00685 mark_type (to_type, FULL_ESCAPE);
00686 mark_type (from_type, FULL_ESCAPE);
00687 break;
00688 }
00689 }
00690 else
00691 {
00692
00693
00694 if (DECL_P (from) && !bitmap_bit_p (results_of_malloc, DECL_UID (from)))
00695 mark_type (to_type, FULL_ESCAPE);
00696 }
00697 else if (from_interesting_type)
00698 mark_type (from_type, FULL_ESCAPE);
00699 }
00700
00701
00702
00703
00704 static void
00705 check_function_parameter_and_return_types (tree fn, bool escapes)
00706 {
00707 tree arg;
00708
00709 if (TYPE_ARG_TYPES (TREE_TYPE (fn)))
00710 {
00711 for (arg = TYPE_ARG_TYPES (TREE_TYPE (fn));
00712 arg && TREE_VALUE (arg) != void_type_node;
00713 arg = TREE_CHAIN (arg))
00714 {
00715 tree type = get_canon_type (TREE_VALUE (arg), false, false);
00716 if (escapes)
00717 mark_interesting_type (type, EXPOSED_PARAMETER);
00718 }
00719 }
00720 else
00721 {
00722
00723
00724
00725
00726
00727 for (arg = DECL_ARGUMENTS (fn); arg; arg = TREE_CHAIN (arg))
00728 {
00729 tree type = get_canon_type (TREE_TYPE (arg), false, false);
00730 if (escapes)
00731 mark_interesting_type (type, EXPOSED_PARAMETER);
00732 }
00733 }
00734 if (escapes)
00735 {
00736 tree type = get_canon_type (TREE_TYPE (TREE_TYPE (fn)), false, false);
00737 mark_interesting_type (type, EXPOSED_PARAMETER);
00738 }
00739 }
00740
00741
00742
00743
00744 static inline void
00745 has_proper_scope_for_analysis (tree t)
00746 {
00747
00748
00749 tree type = get_canon_type (TREE_TYPE (t), false, false);
00750 if (!type) return;
00751
00752 if (lookup_attribute ("used", DECL_ATTRIBUTES (t)))
00753 {
00754 mark_interesting_type (type, FULL_ESCAPE);
00755 return;
00756 }
00757
00758
00759
00760 if (TREE_THIS_VOLATILE (t))
00761 return;
00762
00763
00764 if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
00765 return;
00766
00767 if (DECL_EXTERNAL (t) || TREE_PUBLIC (t))
00768 {
00769
00770
00771
00772
00773
00774 if (TREE_READONLY (t)
00775 && DECL_INITIAL (t)
00776 && is_gimple_min_invariant (DECL_INITIAL (t)))
00777 ;
00778 else
00779 {
00780
00781 mark_interesting_type (type, FULL_ESCAPE);
00782 }
00783 }
00784 }
00785
00786
00787
00788
00789 static void
00790 check_operand (tree t)
00791 {
00792 if (!t) return;
00793
00794
00795
00796 if (TREE_CODE (t) == FUNCTION_DECL)
00797 check_function_parameter_and_return_types (t, true);
00798
00799 else if (TREE_CODE (t) == VAR_DECL)
00800 has_proper_scope_for_analysis (t);
00801 }
00802
00803
00804
00805 static void
00806 check_tree (tree t)
00807 {
00808 if ((TREE_CODE (t) == EXC_PTR_EXPR) || (TREE_CODE (t) == FILTER_EXPR))
00809 return;
00810
00811 while (TREE_CODE (t) == REALPART_EXPR
00812 || TREE_CODE (t) == IMAGPART_EXPR
00813 || handled_component_p (t))
00814 {
00815 if (TREE_CODE (t) == ARRAY_REF)
00816 check_operand (TREE_OPERAND (t, 1));
00817 t = TREE_OPERAND (t, 0);
00818 }
00819
00820 if (INDIRECT_REF_P (t))
00821
00822 check_tree (TREE_OPERAND (t, 0));
00823
00824 if (SSA_VAR_P (t) || (TREE_CODE (t) == FUNCTION_DECL))
00825 check_operand (t);
00826 }
00827
00828
00829 static void
00830 mark_interesting_addressof (tree to_type, tree from_type)
00831 {
00832 int from_uid;
00833 int to_uid;
00834 bitmap type_map;
00835 splay_tree_node result;
00836
00837 from_type = get_canon_type (from_type, false, false);
00838 to_type = get_canon_type (to_type, false, false);
00839
00840 if (!from_type || !to_type)
00841 return;
00842
00843 from_uid = TYPE_UID (from_type);
00844 to_uid = TYPE_UID (to_type);
00845
00846 gcc_assert (ipa_type_escape_star_count_of_interesting_type (from_type) == 0);
00847
00848
00849 result = splay_tree_lookup (uid_to_addressof_down_map,
00850 (splay_tree_key) from_uid);
00851
00852 if (result)
00853 type_map = (bitmap) result->value;
00854 else
00855 {
00856 type_map = BITMAP_ALLOC (&ipa_obstack);
00857 splay_tree_insert (uid_to_addressof_down_map,
00858 from_uid,
00859 (splay_tree_value)type_map);
00860 }
00861 bitmap_set_bit (type_map, TYPE_UID (to_type));
00862
00863
00864 result =
00865 splay_tree_lookup (uid_to_addressof_up_map, (splay_tree_key) to_uid);
00866
00867 if (result)
00868 type_map = (bitmap) result->value;
00869 else
00870 {
00871 type_map = BITMAP_ALLOC (&ipa_obstack);
00872 splay_tree_insert (uid_to_addressof_up_map,
00873 to_uid,
00874 (splay_tree_value)type_map);
00875 }
00876 bitmap_set_bit (type_map, TYPE_UID (to_type));
00877 }
00878
00879
00880
00881 static void
00882 look_for_address_of (tree t)
00883 {
00884 if (TREE_CODE (t) == ADDR_EXPR)
00885 {
00886 tree x = get_base_var (t);
00887 tree cref = TREE_OPERAND (t, 0);
00888
00889
00890
00891 tree fielddecl = NULL_TREE;
00892 while (cref!= x)
00893 {
00894 if (TREE_CODE (cref) == COMPONENT_REF)
00895 {
00896 fielddecl = TREE_OPERAND (cref, 1);
00897 mark_interesting_addressof (TREE_TYPE (fielddecl),
00898 DECL_FIELD_CONTEXT (fielddecl));
00899 }
00900 else if (TREE_CODE (cref) == ARRAY_REF)
00901 get_canon_type (TREE_TYPE (cref), false, false);
00902
00903 cref = TREE_OPERAND (cref, 0);
00904 }
00905
00906 if (TREE_CODE (x) == VAR_DECL)
00907 has_proper_scope_for_analysis (x);
00908 }
00909 }
00910
00911
00912
00913
00914
00915 static void
00916 look_for_casts (tree lhs __attribute__((unused)), tree t)
00917 {
00918 if (is_gimple_cast (t) || TREE_CODE (t) == VIEW_CONVERT_EXPR)
00919 {
00920 tree castfromvar = TREE_OPERAND (t, 0);
00921 check_cast (TREE_TYPE (t), castfromvar);
00922 }
00923 else if (TREE_CODE (t) == COMPONENT_REF
00924 || TREE_CODE (t) == INDIRECT_REF
00925 || TREE_CODE (t) == BIT_FIELD_REF)
00926 {
00927 tree base = get_base_address (t);
00928 while (t != base)
00929 {
00930 t = TREE_OPERAND (t, 0);
00931 if (TREE_CODE (t) == VIEW_CONVERT_EXPR)
00932 {
00933
00934
00935
00936 tree castfromref = TREE_OPERAND (t, 0);
00937 check_cast (TREE_TYPE (t), castfromref);
00938 }
00939 else if (TREE_CODE (t) == COMPONENT_REF)
00940 get_canon_type (TREE_TYPE (TREE_OPERAND (t, 1)), false, false);
00941 }
00942 }
00943 }
00944
00945
00946
00947
00948 static void
00949 check_rhs_var (tree t)
00950 {
00951 look_for_address_of (t);
00952 check_tree(t);
00953 }
00954
00955
00956
00957
00958 static void
00959 check_lhs_var (tree t)
00960 {
00961 check_tree(t);
00962 }
00963
00964
00965
00966
00967
00968
00969
00970
00971 static void
00972 get_asm_expr_operands (tree stmt)
00973 {
00974 int noutputs = list_length (ASM_OUTPUTS (stmt));
00975 const char **oconstraints
00976 = (const char **) alloca ((noutputs) * sizeof (const char *));
00977 int i;
00978 tree link;
00979 const char *constraint;
00980 bool allows_mem, allows_reg, is_inout;
00981
00982 for (i=0, link = ASM_OUTPUTS (stmt); link; ++i, link = TREE_CHAIN (link))
00983 {
00984 oconstraints[i] = constraint
00985 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
00986 parse_output_constraint (&constraint, i, 0, 0,
00987 &allows_mem, &allows_reg, &is_inout);
00988
00989 check_lhs_var (TREE_VALUE (link));
00990 }
00991
00992 for (link = ASM_INPUTS (stmt); link; link = TREE_CHAIN (link))
00993 {
00994 constraint
00995 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
00996 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
00997 oconstraints, &allows_mem, &allows_reg);
00998
00999 check_rhs_var (TREE_VALUE (link));
01000 }
01001
01002
01003
01004
01005
01006
01007
01008 }
01009
01010
01011
01012
01013
01014
01015 static bool
01016 check_call (tree call_expr)
01017 {
01018 int flags = call_expr_flags(call_expr);
01019 tree operand_list = TREE_OPERAND (call_expr, 1);
01020 tree operand;
01021 tree callee_t = get_callee_fndecl (call_expr);
01022 tree argument;
01023 struct cgraph_node* callee;
01024 enum availability avail = AVAIL_NOT_AVAILABLE;
01025
01026 for (operand = operand_list;
01027 operand != NULL_TREE;
01028 operand = TREE_CHAIN (operand))
01029 {
01030 tree argument = TREE_VALUE (operand);
01031 check_rhs_var (argument);
01032 }
01033
01034 if (callee_t)
01035 {
01036 tree arg_type;
01037 tree last_arg_type = NULL;
01038 callee = cgraph_node(callee_t);
01039 avail = cgraph_function_body_availability (callee);
01040
01041
01042
01043 if (TYPE_ARG_TYPES (TREE_TYPE (callee_t)))
01044 {
01045 operand = operand_list;
01046 for (arg_type = TYPE_ARG_TYPES (TREE_TYPE (callee_t));
01047 arg_type && TREE_VALUE (arg_type) != void_type_node;
01048 arg_type = TREE_CHAIN (arg_type))
01049 {
01050 if (operand)
01051 {
01052 argument = TREE_VALUE (operand);
01053 last_arg_type = TREE_VALUE(arg_type);
01054 check_cast (last_arg_type, argument);
01055 operand = TREE_CHAIN (operand);
01056 }
01057 else
01058
01059
01060
01061 break;
01062 }
01063 }
01064 else
01065 {
01066
01067
01068
01069 operand = operand_list;
01070 for (arg_type = DECL_ARGUMENTS (callee_t);
01071 arg_type;
01072 arg_type = TREE_CHAIN (arg_type))
01073 {
01074 if (operand)
01075 {
01076 argument = TREE_VALUE (operand);
01077 last_arg_type = TREE_TYPE(arg_type);
01078 check_cast (last_arg_type, argument);
01079 operand = TREE_CHAIN (operand);
01080 }
01081 else
01082
01083
01084
01085 break;
01086 }
01087 }
01088
01089
01090
01091 arg_type = last_arg_type;
01092 for (;
01093 operand != NULL_TREE;
01094 operand = TREE_CHAIN (operand))
01095 {
01096 argument = TREE_VALUE (operand);
01097 if (arg_type)
01098 check_cast (arg_type, argument);
01099 else
01100 {
01101
01102
01103
01104
01105
01106 tree type = get_canon_type (TREE_TYPE (argument), false, false);
01107 mark_interesting_type (type, FULL_ESCAPE);
01108 }
01109 }
01110 }
01111
01112
01113
01114
01115
01116
01117
01118 if (avail == AVAIL_NOT_AVAILABLE || avail == AVAIL_OVERWRITABLE)
01119 {
01120
01121
01122 for (operand = operand_list;
01123 operand != NULL_TREE;
01124 operand = TREE_CHAIN (operand))
01125 {
01126 tree type =
01127 get_canon_type (TREE_TYPE (TREE_VALUE (operand)), false, false);
01128 mark_interesting_type (type, EXPOSED_PARAMETER);
01129 }
01130
01131 if (callee_t)
01132 {
01133 tree type =
01134 get_canon_type (TREE_TYPE (TREE_TYPE (callee_t)), false, false);
01135 mark_interesting_type (type, EXPOSED_PARAMETER);
01136 }
01137 }
01138 return (flags & ECF_MALLOC);
01139 }
01140
01141
01142
01143 static bool
01144 okay_pointer_operation (enum tree_code code, tree op0, tree op1)
01145 {
01146 tree op0type = TYPE_MAIN_VARIANT (TREE_TYPE (op0));
01147 tree op1type = TYPE_MAIN_VARIANT (TREE_TYPE (op1));
01148 if (POINTER_TYPE_P (op1type))
01149 return false;
01150 switch (code)
01151 {
01152 case MULT_EXPR:
01153 case PLUS_EXPR:
01154 case MINUS_EXPR:
01155
01156 if (operand_equal_p (size_in_bytes (op0type), op1, 0))
01157 return true;
01158
01159
01160 default:
01161 return false;
01162 }
01163 return false;
01164 }
01165
01166
01167
01168
01169
01170
01171
01172
01173 static tree
01174 scan_for_refs (tree *tp, int *walk_subtrees, void *data)
01175 {
01176 struct cgraph_node *fn = data;
01177 tree t = *tp;
01178
01179 switch (TREE_CODE (t))
01180 {
01181 case VAR_DECL:
01182 if (DECL_INITIAL (t))
01183 walk_tree (&DECL_INITIAL (t), scan_for_refs, fn, visited_nodes);
01184 *walk_subtrees = 0;
01185 break;
01186
01187 case MODIFY_EXPR:
01188 {
01189
01190 tree lhs = TREE_OPERAND (t, 0);
01191 tree rhs = TREE_OPERAND (t, 1);
01192
01193 check_lhs_var (lhs);
01194 check_cast (TREE_TYPE (lhs), rhs);
01195
01196
01197
01198
01199 switch (TREE_CODE_CLASS (TREE_CODE (rhs)))
01200 {
01201 case tcc_binary:
01202 {
01203 tree op0 = TREE_OPERAND (rhs, 0);
01204 tree type0 = get_canon_type (TREE_TYPE (op0), false, false);
01205 tree op1 = TREE_OPERAND (rhs, 1);
01206 tree type1 = get_canon_type (TREE_TYPE (op1), false, false);
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219 if (type0 && POINTER_TYPE_P (type0)
01220 && !okay_pointer_operation (TREE_CODE (rhs), op0, op1))
01221 mark_interesting_type (type0, FULL_ESCAPE);
01222 if (type1 && POINTER_TYPE_P (type1)
01223 && !okay_pointer_operation (TREE_CODE (rhs), op1, op0))
01224 mark_interesting_type (type1, FULL_ESCAPE);
01225
01226 look_for_casts (lhs, op0);
01227 look_for_casts (lhs, op1);
01228 check_rhs_var (op0);
01229 check_rhs_var (op1);
01230 }
01231 break;
01232 case tcc_unary:
01233 {
01234 tree op0 = TREE_OPERAND (rhs, 0);
01235 tree type0 = get_canon_type (TREE_TYPE (op0), false, false);
01236
01237
01238
01239 if (type0 && (TREE_CODE (op0) == NEGATE_EXPR
01240 || TREE_CODE (op0) == ABS_EXPR)
01241 && POINTER_TYPE_P (type0))
01242 {
01243 mark_interesting_type (type0, FULL_ESCAPE);
01244 }
01245 check_rhs_var (op0);
01246 look_for_casts (lhs, op0);
01247 look_for_casts (lhs, rhs);
01248 }
01249
01250 break;
01251 case tcc_reference:
01252 look_for_casts (lhs, rhs);
01253 check_rhs_var (rhs);
01254 break;
01255 case tcc_declaration:
01256 check_rhs_var (rhs);
01257 break;
01258 case tcc_expression:
01259 switch (TREE_CODE (rhs))
01260 {
01261 case ADDR_EXPR:
01262 look_for_casts (lhs, TREE_OPERAND (rhs, 0));
01263 check_rhs_var (rhs);
01264 break;
01265 case CALL_EXPR:
01266
01267
01268
01269 if (check_call (rhs))
01270 bitmap_set_bit (results_of_malloc, DECL_UID (lhs));
01271 break;
01272 default:
01273 break;
01274 }
01275 break;
01276 default:
01277 break;
01278 }
01279 *walk_subtrees = 0;
01280 }
01281 break;
01282
01283 case ADDR_EXPR:
01284
01285
01286 check_rhs_var (t);
01287 *walk_subtrees = 0;
01288 break;
01289
01290 case CALL_EXPR:
01291 check_call (t);
01292 *walk_subtrees = 0;
01293 break;
01294
01295 case ASM_EXPR:
01296 get_asm_expr_operands (t);
01297 *walk_subtrees = 0;
01298 break;
01299
01300 default:
01301 break;
01302 }
01303 return NULL;
01304 }
01305
01306
01307
01308
01309 static void
01310 ipa_init (void)
01311 {
01312 bitmap_obstack_initialize (&ipa_obstack);
01313 global_types_exposed_parameter = BITMAP_ALLOC (&ipa_obstack);
01314 global_types_full_escape = BITMAP_ALLOC (&ipa_obstack);
01315 global_types_seen = BITMAP_ALLOC (&ipa_obstack);
01316 results_of_malloc = BITMAP_ALLOC (&ipa_obstack);
01317
01318 uid_to_canon_type = splay_tree_new (splay_tree_compare_ints, 0, 0);
01319 all_canon_types = splay_tree_new (compare_type_brand, 0, 0);
01320 type_to_canon_type = splay_tree_new (splay_tree_compare_pointers, 0, 0);
01321 uid_to_subtype_map = splay_tree_new (splay_tree_compare_ints, 0, 0);
01322 uid_to_addressof_down_map = splay_tree_new (splay_tree_compare_ints, 0, 0);
01323 uid_to_addressof_up_map = splay_tree_new (splay_tree_compare_ints, 0, 0);
01324
01325
01326
01327
01328
01329 visited_nodes = pointer_set_create ();
01330 initialized = true;
01331 }
01332
01333
01334
01335
01336
01337
01338
01339 static void
01340 analyze_variable (struct cgraph_varpool_node *vnode)
01341 {
01342 tree global = vnode->decl;
01343 tree type = get_canon_type (TREE_TYPE (global), false, false);
01344
01345
01346
01347
01348 if (vnode->externally_visible)
01349 mark_interesting_type (type, FULL_ESCAPE);
01350
01351 gcc_assert (TREE_CODE (global) == VAR_DECL);
01352
01353 if (DECL_INITIAL (global))
01354 walk_tree (&DECL_INITIAL (global), scan_for_refs, NULL, visited_nodes);
01355 }
01356
01357
01358
01359
01360 static void
01361 analyze_function (struct cgraph_node *fn)
01362 {
01363 tree decl = fn->decl;
01364 check_function_parameter_and_return_types (decl,
01365 fn->local.externally_visible);
01366 if (dump_file)
01367 fprintf (dump_file, "\n local analysis of %s", cgraph_node_name (fn));
01368
01369 {
01370 struct function *this_cfun = DECL_STRUCT_FUNCTION (decl);
01371 basic_block this_block;
01372
01373 FOR_EACH_BB_FN (this_block, this_cfun)
01374 {
01375 block_stmt_iterator bsi;
01376 for (bsi = bsi_start (this_block); !bsi_end_p (bsi); bsi_next (&bsi))
01377 walk_tree (bsi_stmt_ptr (bsi), scan_for_refs,
01378 fn, visited_nodes);
01379 }
01380 }
01381
01382
01383 if (DECL_STRUCT_FUNCTION (decl))
01384 {
01385 tree step;
01386 for (step = DECL_STRUCT_FUNCTION (decl)->unexpanded_var_list;
01387 step;
01388 step = TREE_CHAIN (step))
01389 {
01390 tree var = TREE_VALUE (step);
01391 if (TREE_CODE (var) == VAR_DECL
01392 && DECL_INITIAL (var)
01393 && !TREE_STATIC (var))
01394 walk_tree (&DECL_INITIAL (var), scan_for_refs,
01395 fn, visited_nodes);
01396 get_canon_type (TREE_TYPE (var), false, false);
01397 }
01398 }
01399 }
01400
01401
01402
01403
01404 static tree
01405 type_for_uid (int uid)
01406 {
01407 splay_tree_node result =
01408 splay_tree_lookup (uid_to_canon_type, (splay_tree_key) uid);
01409
01410 if (result)
01411 return (tree) result->value;
01412 else return NULL;
01413 }
01414
01415
01416
01417
01418
01419 static bitmap
01420 subtype_map_for_uid (int uid, bool create)
01421 {
01422 splay_tree_node result = splay_tree_lookup (uid_to_subtype_map,
01423 (splay_tree_key) uid);
01424
01425 if (result)
01426 return (bitmap) result->value;
01427 else if (create)
01428 {
01429 bitmap subtype_map = BITMAP_ALLOC (&ipa_obstack);
01430 splay_tree_insert (uid_to_subtype_map,
01431 uid,
01432 (splay_tree_value)subtype_map);
01433 return subtype_map;
01434 }
01435 else return NULL;
01436 }
01437
01438
01439
01440
01441
01442
01443 static void
01444 close_type_seen (tree type)
01445 {
01446 tree field;
01447 int i, uid;
01448 tree binfo, base_binfo;
01449
01450
01451 type = get_canon_type (type, true, true);
01452 if (!type)
01453 return;
01454
01455 uid = TYPE_UID (type);
01456
01457 if (bitmap_bit_p (been_there_done_that, uid))
01458 return;
01459 bitmap_set_bit (been_there_done_that, uid);
01460
01461
01462
01463 if (TYPE_BINFO (type))
01464 for (binfo = TYPE_BINFO (type), i = 0;
01465 BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
01466 {
01467 tree binfo_type = BINFO_TYPE (base_binfo);
01468 bitmap subtype_map = subtype_map_for_uid
01469 (TYPE_UID (TYPE_MAIN_VARIANT (binfo_type)), true);
01470 bitmap_set_bit (subtype_map, uid);
01471 close_type_seen (get_canon_type (binfo_type, true, true));
01472 }
01473
01474
01475
01476 for (field = TYPE_FIELDS (type);
01477 field;
01478 field = TREE_CHAIN (field))
01479 {
01480 tree field_type;
01481 if (TREE_CODE (field) != FIELD_DECL)
01482 continue;
01483
01484 field_type = TREE_TYPE (field);
01485 if (ipa_type_escape_star_count_of_interesting_or_array_type (field_type) >= 0)
01486 close_type_seen (get_canon_type (field_type, true, true));
01487 }
01488 }
01489
01490
01491
01492
01493
01494
01495 static void
01496 close_type_exposed_parameter (tree type)
01497 {
01498 tree field;
01499 int uid;
01500
01501 type = get_canon_type (type, false, false);
01502 if (!type)
01503 return;
01504 uid = TYPE_UID (type);
01505 gcc_assert (!POINTER_TYPE_P (type));
01506
01507 if (bitmap_bit_p (been_there_done_that, uid))
01508 return;
01509 bitmap_set_bit (been_there_done_that, uid);
01510
01511
01512
01513 for (field = TYPE_FIELDS (type);
01514 field;
01515 field = TREE_CHAIN (field))
01516 {
01517 tree field_type;
01518
01519 if (TREE_CODE (field) != FIELD_DECL)
01520 continue;
01521
01522 field_type = get_canon_type (TREE_TYPE (field), false, false);
01523 mark_interesting_type (field_type, EXPOSED_PARAMETER);
01524
01525
01526 if (ipa_type_escape_star_count_of_interesting_type (field_type) == 0)
01527 close_type_exposed_parameter (field_type);
01528 }
01529 }
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545 static void
01546 close_type_full_escape (tree type)
01547 {
01548 tree field;
01549 unsigned int i;
01550 int uid;
01551 tree binfo, base_binfo;
01552 bitmap_iterator bi;
01553 bitmap subtype_map;
01554 splay_tree_node address_result;
01555
01556
01557 type = get_canon_type (type, true, true);
01558 if (!type)
01559 return;
01560 uid = TYPE_UID (type);
01561
01562 if (bitmap_bit_p (been_there_done_that, uid))
01563 return;
01564 bitmap_set_bit (been_there_done_that, uid);
01565
01566 subtype_map = subtype_map_for_uid (uid, false);
01567
01568
01569
01570 if (TYPE_BINFO (type))
01571 for (binfo = TYPE_BINFO (type), i = 0;
01572 BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
01573 {
01574 tree binfotype = BINFO_TYPE (base_binfo);
01575 binfotype = mark_type (binfotype, FULL_ESCAPE);
01576 close_type_full_escape (binfotype);
01577 }
01578
01579
01580
01581 if (subtype_map)
01582 EXECUTE_IF_SET_IN_BITMAP (subtype_map, 0, i, bi)
01583 {
01584 tree subtype = type_for_uid (i);
01585 subtype = mark_type (subtype, FULL_ESCAPE);
01586 close_type_full_escape (subtype);
01587 }
01588
01589
01590
01591 for (field = TYPE_FIELDS (type);
01592 field;
01593 field = TREE_CHAIN (field))
01594 {
01595 tree field_type;
01596 if (TREE_CODE (field) != FIELD_DECL)
01597 continue;
01598
01599 field_type = TREE_TYPE (field);
01600 if (ipa_type_escape_star_count_of_interesting_or_array_type (field_type) >= 0)
01601 {
01602 field_type = mark_type (field_type, FULL_ESCAPE);
01603 close_type_full_escape (field_type);
01604 }
01605 }
01606
01607
01608
01609 address_result = splay_tree_lookup (uid_to_addressof_up_map,
01610 (splay_tree_key) uid);
01611 if (address_result)
01612 {
01613 bitmap containing_classes = (bitmap) address_result->value;
01614 EXECUTE_IF_SET_IN_BITMAP (containing_classes, 0, i, bi)
01615 {
01616 close_type_full_escape (type_for_uid (i));
01617 }
01618 }
01619 }
01620
01621
01622
01623
01624
01625 static bitmap
01626 close_addressof_down (int uid)
01627 {
01628 bitmap_iterator bi;
01629 splay_tree_node result =
01630 splay_tree_lookup (uid_to_addressof_down_map, (splay_tree_key) uid);
01631 bitmap map = NULL;
01632 bitmap new_map;
01633 unsigned int i;
01634
01635 if (result)
01636 map = (bitmap) result->value;
01637 else
01638 return NULL;
01639
01640 if (bitmap_bit_p (been_there_done_that, uid))
01641 return map;
01642 bitmap_set_bit (been_there_done_that, uid);
01643
01644
01645
01646 if (bitmap_bit_p (global_types_full_escape, uid))
01647 {
01648 BITMAP_FREE (map);
01649 splay_tree_remove (uid_to_addressof_down_map, (splay_tree_key) uid);
01650 return NULL;
01651 }
01652
01653
01654
01655 new_map = BITMAP_ALLOC (&ipa_obstack);
01656
01657 EXECUTE_IF_SET_IN_BITMAP (map, 0, i, bi)
01658 {
01659 bitmap submap = close_addressof_down (i);
01660 bitmap_set_bit (new_map, i);
01661 if (submap)
01662 bitmap_ior_into (new_map, submap);
01663 }
01664 result->value = (splay_tree_value) new_map;
01665
01666 BITMAP_FREE (map);
01667 return new_map;
01668 }
01669
01670
01671
01672
01673 static unsigned int
01674 type_escape_execute (void)
01675 {
01676 struct cgraph_node *node;
01677 struct cgraph_varpool_node *vnode;
01678 unsigned int i;
01679 bitmap_iterator bi;
01680 splay_tree_node result;
01681
01682 ipa_init ();
01683
01684
01685 for (vnode = cgraph_varpool_nodes_queue; vnode; vnode = vnode->next_needed)
01686 analyze_variable (vnode);
01687
01688
01689
01690
01691
01692
01693
01694
01695 for (node = cgraph_nodes; node; node = node->next)
01696 if (node->analyzed
01697 && (cgraph_is_master_clone (node)
01698 || (cgraph_function_body_availability (node) == AVAIL_OVERWRITABLE)))
01699 analyze_function (node);
01700
01701
01702 pointer_set_destroy (visited_nodes);
01703 visited_nodes = NULL;
01704
01705
01706
01707
01708 been_there_done_that = BITMAP_ALLOC (&ipa_obstack);
01709 bitmap_tmp = BITMAP_ALLOC (&ipa_obstack);
01710
01711
01712
01713
01714 bitmap_copy (bitmap_tmp, global_types_seen);
01715 EXECUTE_IF_SET_IN_BITMAP (bitmap_tmp, 0, i, bi)
01716 {
01717 tree type = type_for_uid (i);
01718
01719 if (ipa_type_escape_star_count_of_interesting_or_array_type (type) >= 0)
01720 close_type_seen (type);
01721 }
01722 bitmap_clear (been_there_done_that);
01723
01724
01725
01726 bitmap_copy (bitmap_tmp, global_types_exposed_parameter);
01727 EXECUTE_IF_SET_IN_BITMAP (bitmap_tmp, 0, i, bi)
01728 {
01729 close_type_exposed_parameter (type_for_uid (i));
01730 }
01731 bitmap_clear (been_there_done_that);
01732
01733
01734
01735 bitmap_copy (bitmap_tmp, global_types_full_escape);
01736 EXECUTE_IF_SET_IN_BITMAP (bitmap_tmp, 0, i, bi)
01737 {
01738 close_type_full_escape (type_for_uid (i));
01739 }
01740 bitmap_clear (been_there_done_that);
01741
01742
01743
01744
01745
01746
01747 result = splay_tree_min (uid_to_addressof_down_map);
01748 while (result)
01749 {
01750 int uid = result->key;
01751
01752
01753 close_addressof_down (uid);
01754 result = splay_tree_successor (uid_to_addressof_down_map, uid);
01755 }
01756
01757
01758
01759 result = splay_tree_min (all_canon_types);
01760 while (result)
01761 {
01762 tree type = (tree) result->value;
01763 tree key = (tree) result->key;
01764 if (POINTER_TYPE_P (type)
01765 || TREE_CODE (type) == ARRAY_TYPE)
01766 {
01767 splay_tree_remove (all_canon_types, (splay_tree_key) result->key);
01768 splay_tree_remove (type_to_canon_type, (splay_tree_key) type);
01769 splay_tree_remove (uid_to_canon_type, (splay_tree_key) TYPE_UID (type));
01770 bitmap_clear_bit (global_types_seen, TYPE_UID (type));
01771 }
01772 result = splay_tree_successor (all_canon_types, (splay_tree_key) key);
01773 }
01774
01775 if (dump_file)
01776 {
01777 EXECUTE_IF_SET_IN_BITMAP (global_types_seen, 0, i, bi)
01778 {
01779
01780
01781
01782 tree type = type_for_uid (i);
01783 fprintf(dump_file, "type %d ", i);
01784 print_generic_expr (dump_file, type, 0);
01785 if (bitmap_bit_p (global_types_full_escape, i))
01786 fprintf(dump_file, " escaped\n");
01787 else
01788 fprintf(dump_file, " contained\n");
01789 }
01790 }
01791
01792
01793 result = splay_tree_min (uid_to_addressof_up_map);
01794 while (result)
01795 {
01796 int uid = (int)result->key;
01797 bitmap bm = (bitmap)result->value;
01798
01799 BITMAP_FREE (bm);
01800 splay_tree_remove (uid_to_addressof_up_map, (splay_tree_key) uid);
01801 result = splay_tree_successor (uid_to_addressof_up_map, uid);
01802 }
01803
01804
01805 result = splay_tree_min (uid_to_subtype_map);
01806 while (result)
01807 {
01808 bitmap b = (bitmap)result->value;
01809 BITMAP_FREE(b);
01810 splay_tree_remove (uid_to_subtype_map, result->key);
01811 result = splay_tree_min (uid_to_subtype_map);
01812 }
01813 splay_tree_delete (uid_to_subtype_map);
01814 uid_to_subtype_map = NULL;
01815
01816 BITMAP_FREE (global_types_exposed_parameter);
01817 BITMAP_FREE (been_there_done_that);
01818 BITMAP_FREE (bitmap_tmp);
01819 BITMAP_FREE (results_of_malloc);
01820 return 0;
01821 }
01822
01823 static bool
01824 gate_type_escape_vars (void)
01825 {
01826 return (flag_unit_at_a_time != 0 && flag_ipa_type_escape
01827
01828 && !(errorcount || sorrycount));
01829 }
01830
01831 struct tree_opt_pass pass_ipa_type_escape =
01832 {
01833 "type-escape-var",
01834 gate_type_escape_vars,
01835 type_escape_execute,
01836 NULL,
01837 NULL,
01838 0,
01839 TV_IPA_TYPE_ESCAPE,
01840 0,
01841 0,
01842 0,
01843 0,
01844 0,
01845 0
01846 };
01847