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
00037
00038
00039
00040 #define __STDC_LIMIT_MACROS
00041 #include <stdint.h>
00042 #include "defs.h"
00043 #include "symtab.h"
00044
00045 #include "ipc_symtab_merge.h"
00046 #include "ipc_ty_hash.h"
00047 #include "ipc_type_merge.h"
00048
00049 #include "config_ipa.h"
00050 #include <ext/hash_set>
00051 #include <ext/hash_map>
00052 using __gnu_cxx::hash_set;
00053 using __gnu_cxx::hash_map;
00054
00055
00056 hash_map <STR_IDX, TY_INDEX, __new_hash::hash<STR_IDX>, std::equal_to<STR_IDX> > struct_by_name_idx;
00057
00058
00059 hash_set <TY_INDEX> to_update_incomplete_ty;
00060
00061
00062 hash_set <TY_INDEX> updating_incomplete_ty;
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 static inline BOOL
00081 ARB_equal (const ARB_HANDLE merged_arb, const ARB& new_arb)
00082 {
00083 const UINT64* p1 = reinterpret_cast<const UINT64*> (merged_arb.Entry ());
00084 const UINT64* p2 = reinterpret_cast<const UINT64*> (&new_arb);
00085
00086 return (p1[0] == p2[0] &&
00087 p1[1] == p2[1] &&
00088 p1[2] == p2[2] &&
00089 p1[3] == p2[3]);
00090 }
00091
00092
00093
00094
00095
00096 static const IPC_GLOBAL_TABS* file_tables;
00097
00098 struct array_access
00099 {
00100 TY_KIND kind () const { return KIND_ARRAY; }
00101
00102 UINT kid_count () const { return 1; }
00103
00104 TY_IDX kid (const TY& ty, UINT) const {
00105 return TY_etype (ty);
00106 }
00107
00108
00109 BOOL validate (const TY& merged_ty, const TY& new_ty) const {
00110 return Partial_Compare_Arb (TY_arb (merged_ty),
00111 file_tables->arb_tab + new_ty.Arb ());
00112 }
00113
00114 };
00115
00116
00117 struct struct_access
00118 {
00119 const TY& new_ty;
00120 const TY& merged_ty;
00121
00122 struct_access (const TY& _new_ty, const TY& _merged_ty) :
00123 new_ty (_new_ty), merged_ty (_merged_ty) {}
00124
00125 TY_KIND kind () const { return KIND_STRUCT; }
00126
00127 UINT kid_count () const {
00128 if (new_ty.Fld () == 0)
00129 return 0;
00130 UINT count = 0;
00131 const FLD* fld = file_tables->fld_tab + new_ty.Fld () ;
00132 do {
00133 ++count;
00134 } while ((fld++->flags & FLD_LAST_FIELD) == 0);
00135 return count;
00136 }
00137
00138 TY_IDX kid (const TY& ty, UINT i) const {
00139 if (&ty == &new_ty) {
00140 const FLD* fld = file_tables->fld_tab + new_ty.Fld ();
00141 return fld[i].type;
00142 } else {
00143 FLD_HANDLE fld (TY_fld (merged_ty).Idx () + i);
00144 return FLD_type (fld);
00145 }
00146 }
00147
00148 BOOL validate (const TY& merged_ty, const TY& new_ty) const {
00149 if (new_ty.Fld () == 0 || merged_ty.Fld () == 0)
00150 return new_ty.Fld () == merged_ty.Fld ();
00151 return Partial_Compare_Fld (TY_fld (merged_ty),
00152 file_tables->fld_tab + new_ty.Fld ());
00153 }
00154
00155 };
00156
00157
00158 struct pointer_access
00159 {
00160 TY_KIND kind () const { return KIND_POINTER; }
00161
00162 UINT kid_count () const { return 1; }
00163
00164 TY_IDX kid (const TY& ty, UINT) const {
00165 return TY_pointed (ty);
00166 }
00167
00168 BOOL validate (const TY&, const TY&) const {
00169 return TRUE;
00170 }
00171 };
00172
00173
00174 struct function_access
00175 {
00176 const TY& new_ty;
00177 const TY& merged_ty;
00178
00179 function_access (const TY& _new_ty, const TY& _merged_ty) :
00180 new_ty (_new_ty), merged_ty (_merged_ty) {}
00181
00182 TY_KIND kind () const { return KIND_FUNCTION; }
00183
00184 UINT kid_count () const {
00185 UINT count = 0;
00186 const TYLIST* tylist = file_tables->tylist_tab + TY_tylist (new_ty);
00187 while (*tylist != 0) {
00188 ++count;
00189 ++tylist;
00190 }
00191 return count;
00192 }
00193
00194 TY_IDX kid (const TY& ty, UINT i) const {
00195 if (&ty == &new_ty) {
00196 return file_tables->tylist_tab[TY_tylist (ty) + i];
00197 } else {
00198 TYLIST_IDX idx = TY_tylist (merged_ty) + i;
00199 return Tylist_Table[idx];
00200 }
00201 }
00202
00203 BOOL validate (const TY& merged_ty, const TY& new_ty) const {
00204 return new_ty.Pu_flags () == merged_ty.Pu_flags ();
00205 }
00206 };
00207
00208
00209
00210
00211
00212
00213
00214 enum VALIDATION_STATE
00215 {
00216 VALIDATE_OK = 1,
00217 VALIDATE_FAIL = 2,
00218 VALIDATE_COMMIT = 3
00219
00220 };
00221
00222
00223 static VALIDATION_STATE
00224 Validate_Recursive_Type (TY_INDEX index, TY_IDX_MAP& ty_map,
00225 const SYMSTR_IDX_MAP& str_map, TY_IDX merged_ty_idx);
00226
00227 namespace
00228 {
00229
00230
00231
00232
00233 inline BOOL
00234 TY_is_incomplete (TY_IDX tyi, BOOL in_file) {
00235 if (in_file) {
00236 TY &ty = file_tables->ty_tab[TY_IDX_index(tyi)];
00237 if (TY_kind(ty) == KIND_STRUCT)
00238 return TY_is_incomplete_struct(ty);
00239 if (TY_kind(ty) == KIND_POINTER)
00240 return TY_is_incomplete_struct(file_tables->ty_tab[TY_IDX_index(TY_pointed(ty))]);
00241 }
00242 else {
00243 if (TY_kind(tyi) == KIND_STRUCT)
00244 return TY_is_incomplete_struct(tyi) || TY_align(tyi) == 1;
00245 if (TY_kind(tyi) == KIND_POINTER)
00246 return TY_is_incomplete_struct(TY_pointed(tyi))
00247 || TY_align(TY_pointed(tyi)) == 1;
00248 }
00249 return FALSE;
00250 }
00251
00252
00253 template <class ACCESS>
00254 VALIDATION_STATE
00255 Partial_Match (const TY& merged_ty, const TY& new_ty,
00256 TY_IDX_MAP& ty_map,
00257 const SYMSTR_IDX_MAP& str_map,
00258 const ACCESS& ty_node)
00259 {
00260 Is_True (TY_kind (new_ty) == ty_node.kind (),
00261 ("Invalid type attributes for array"));
00262
00263 if (TY_size (merged_ty) != TY_size (new_ty) ||
00264 TY_kind (merged_ty) != TY_kind (new_ty) ||
00265 TY_mtype (merged_ty) != TY_mtype (new_ty) ||
00266 TY_flags (merged_ty) != TY_flags (new_ty) ||
00267 TY_name_idx (merged_ty) != str_map[TY_name_idx (new_ty)])
00268 return VALIDATE_FAIL;
00269
00270 UINT kid_count = ty_node.kid_count ();
00271 UINT i;
00272 for (i = 0; i < kid_count; ++i) {
00273 if (TY_IDX_Attributes (ty_node.kid (merged_ty, i)) !=
00274 TY_IDX_Attributes (ty_node.kid (new_ty, i)))
00275 return VALIDATE_FAIL;
00276 }
00277
00278 if (! ty_node.validate (merged_ty, new_ty))
00279 return VALIDATE_FAIL;
00280
00281 BOOL all_kids_committed = TRUE;
00282
00283 for (i = 0; i < kid_count; ++i) {
00284 TY_INDEX kid_index = TY_IDX_index (ty_node.kid (new_ty, i));
00285 TY_IDX kid_mapped_idx = ty_map.map_[kid_index];
00286
00287 if (TY_Inserted (kid_mapped_idx))
00288 return VALIDATE_FAIL;
00289
00290 if (Is_TY_Temp_Idx (kid_mapped_idx)) {
00291 all_kids_committed = FALSE;
00292 Clean_TY_IDX (kid_mapped_idx);
00293 }
00294
00295 if (Valid_TY_IDX (kid_mapped_idx)) {
00296 if (TY_IDX_index (ty_node.kid (merged_ty, i)) !=
00297 TY_IDX_index (kid_mapped_idx))
00298 return VALIDATE_FAIL;
00299 } else {
00300 VALIDATION_STATE v_state =
00301 Validate_Recursive_Type (kid_index, ty_map, str_map,
00302 ty_node.kid (merged_ty, i));
00303
00304 if (v_state == VALIDATE_FAIL)
00305 return v_state;
00306 else if (v_state == VALIDATE_OK)
00307 all_kids_committed = FALSE;
00308 }
00309 }
00310
00311
00312 if (all_kids_committed) {
00313 return VALIDATE_COMMIT;
00314 } else
00315 return VALIDATE_OK;
00316 }
00317
00318 template <class ACCESS>
00319 VALIDATION_STATE
00320 New_Partial_Match (const TY& merged_ty, const TY& new_ty,
00321 TY_IDX_MAP& ty_map,
00322 const SYMSTR_IDX_MAP& str_map,
00323 const ACCESS& ty_node)
00324 {
00325 Is_True (TY_kind (new_ty) == ty_node.kind (),
00326 ("Invalid type attributes for array"));
00327
00328 if (TY_kind (merged_ty) != TY_kind (new_ty))
00329 return VALIDATE_FAIL;
00330 if (TY_kind (merged_ty) == KIND_STRUCT || TY_kind (merged_ty) == KIND_ARRAY) {
00331 if (TY_anonymous(merged_ty) || TY_anonymous(new_ty)) {
00332 if (TY_anonymous(merged_ty) != TY_anonymous(new_ty))
00333 return VALIDATE_FAIL;
00334 }
00335 else {
00336 if (TY_name_idx (merged_ty) != str_map[TY_name_idx (new_ty)])
00337 return VALIDATE_FAIL;
00338 }
00339 if (TY_is_incomplete_struct(merged_ty) || TY_is_incomplete_struct(new_ty))
00340 return VALIDATE_OK;
00341 }
00342 else
00343 if (TY_name_idx (merged_ty) != str_map[TY_name_idx (new_ty)])
00344 return VALIDATE_FAIL;
00345 if (TY_size (merged_ty) != TY_size (new_ty) ||
00346 TY_mtype (merged_ty) != TY_mtype (new_ty) ||
00347 TY_flags (merged_ty) != TY_flags (new_ty))
00348 return VALIDATE_FAIL;
00349
00350 UINT kid_count = ty_node.kid_count ();
00351 UINT i;
00352 for (i = 0; i < kid_count; ++i) {
00353 TY_IDX merged_kid_idx = ty_node.kid(merged_ty, i);
00354 TY_IDX new_kid_idx = ty_node.kid(new_ty, i);
00355
00356 if ((TY_IDX_Attributes(merged_kid_idx) != TY_IDX_Attributes(new_kid_idx))
00357 && (!TY_is_incomplete(merged_kid_idx, FALSE))
00358 && (!TY_is_incomplete(new_kid_idx, TRUE)))
00359 return VALIDATE_FAIL;
00360 }
00361
00362 if (! ty_node.validate (merged_ty, new_ty))
00363 return VALIDATE_FAIL;
00364
00365 BOOL all_kids_committed = TRUE;
00366
00367 for (i = 0; i < kid_count; ++i) {
00368 TY_INDEX kid_index = TY_IDX_index (ty_node.kid (new_ty, i));
00369 TY_IDX kid_mapped_idx = ty_map.map_[kid_index];
00370
00371 if (TY_Inserted (kid_mapped_idx))
00372 return VALIDATE_FAIL;
00373
00374 if (Is_TY_Temp_Idx (kid_mapped_idx)) {
00375 all_kids_committed = FALSE;
00376 Clean_TY_IDX (kid_mapped_idx);
00377 }
00378
00379 if (Valid_TY_IDX (kid_mapped_idx)) {
00380 if (TY_IDX_index (ty_node.kid (merged_ty, i)) !=
00381 TY_IDX_index (kid_mapped_idx))
00382 return VALIDATE_FAIL;
00383 } else {
00384 VALIDATION_STATE v_state =
00385 Validate_Recursive_Type (kid_index, ty_map, str_map,
00386 ty_node.kid (merged_ty, i));
00387
00388 if (v_state == VALIDATE_FAIL)
00389 return v_state;
00390 else if (v_state == VALIDATE_OK)
00391 all_kids_committed = FALSE;
00392 }
00393 }
00394
00395
00396 if (all_kids_committed) {
00397 return VALIDATE_COMMIT;
00398 } else
00399 return VALIDATE_OK;
00400 }
00401 }
00402
00403
00404 static VALIDATION_STATE
00405 Validate_Recursive_Type (TY_INDEX index, TY_IDX_MAP& ty_map,
00406 const SYMSTR_IDX_MAP& str_map, TY_IDX merged_ty_idx)
00407 {
00408 TY_IDX& my_mapped_idx = ty_map.map_[index];
00409
00410 Is_True (! Valid_TY_IDX (my_mapped_idx),
00411 ("Invalid call to Validate_Recursive_Type"));
00412
00413 const TY& new_ty = file_tables->ty_tab[index];
00414 const TY& merged_ty = Ty_Table[merged_ty_idx];
00415
00416 if (TY_kind (new_ty) != TY_kind (merged_ty))
00417 return VALIDATE_FAIL;
00418
00419 VALIDATION_STATE v_state;
00420
00421 switch (TY_kind (new_ty)) {
00422
00423 case KIND_SCALAR:
00424 case KIND_VOID:
00425 ty_map.set_map (index, Insert_Unique_Ty (new_ty));
00426 if (ty_map.map_[index] == merged_ty_idx) {
00427 return VALIDATE_COMMIT;
00428 } else
00429 return VALIDATE_FAIL;
00430
00431 case KIND_ARRAY:
00432 Set_TY_Temp_Idx (my_mapped_idx, merged_ty_idx);
00433 if (IPA_Enable_Old_Type_Merge)
00434 v_state = Partial_Match (merged_ty, new_ty, ty_map, str_map,
00435 array_access ());
00436 else
00437 v_state = New_Partial_Match (merged_ty, new_ty, ty_map, str_map,
00438 array_access ());
00439 break;
00440
00441 case KIND_STRUCT:
00442 Set_TY_Temp_Idx (my_mapped_idx, merged_ty_idx);
00443 if (IPA_Enable_Old_Type_Merge)
00444 v_state = Partial_Match (merged_ty, new_ty, ty_map, str_map,
00445 struct_access (new_ty, merged_ty));
00446 else
00447 v_state = New_Partial_Match (merged_ty, new_ty, ty_map, str_map,
00448 struct_access (new_ty, merged_ty));
00449 break;
00450
00451 case KIND_POINTER:
00452 Set_TY_Temp_Idx (my_mapped_idx, merged_ty_idx);
00453 if (IPA_Enable_Old_Type_Merge)
00454 v_state = Partial_Match (merged_ty, new_ty, ty_map, str_map,
00455 pointer_access ());
00456 else
00457 v_state = New_Partial_Match (merged_ty, new_ty, ty_map, str_map,
00458 pointer_access ());
00459 break;
00460
00461 case KIND_FUNCTION:
00462 Set_TY_Temp_Idx (my_mapped_idx, merged_ty_idx);
00463 if (IPA_Enable_Old_Type_Merge)
00464 v_state = Partial_Match (merged_ty, new_ty, ty_map, str_map,
00465 function_access (new_ty, merged_ty));
00466 else
00467 v_state = New_Partial_Match (merged_ty, new_ty, ty_map, str_map,
00468 function_access (new_ty, merged_ty));
00469 break;
00470 }
00471
00472 if (v_state == VALIDATE_COMMIT)
00473 ty_map.set_map (index, Insert_Unique_Ty (new_ty));
00474 return v_state;
00475 }
00476
00477 static void
00478 Clear_All_Temp_Idx (TY_INDEX index, TY_IDX_MAP& ty_map);
00479
00480 namespace {
00481
00482 template <class ACCESS>
00483 void
00484 Clear_Temp_Idx_Specific (const TY& new_ty, TY_IDX_MAP& ty_map,
00485 const ACCESS& ty_node)
00486 {
00487 UINT kid_count = ty_node.kid_count ();
00488 for (UINT i = 0; i < kid_count; ++i) {
00489 TY_INDEX kid_index = TY_IDX_index (ty_node.kid (new_ty, i));
00490 TY_IDX mapped_kid_idx = ty_map.map_[kid_index];
00491 if (Is_TY_Temp_Idx (mapped_kid_idx))
00492 Clear_All_Temp_Idx (kid_index, ty_map);
00493 }
00494 }
00495 }
00496
00497
00498
00499 static void
00500 Clear_All_Temp_Idx (TY_INDEX index, TY_IDX_MAP& ty_map)
00501 {
00502 TY_IDX& my_mapped_idx = ty_map.map_[index];
00503
00504 if (! Is_TY_Temp_Idx (my_mapped_idx))
00505 return;
00506
00507 Clear_TY_Temp_Idx (my_mapped_idx);
00508
00509 const TY& new_ty = file_tables->ty_tab[index];
00510
00511 switch (TY_kind (new_ty)) {
00512 case KIND_SCALAR:
00513 case KIND_VOID:
00514 return;
00515
00516 case KIND_ARRAY:
00517 Clear_Temp_Idx_Specific (new_ty, ty_map, array_access ());
00518 break;
00519
00520 case KIND_STRUCT:
00521 Clear_Temp_Idx_Specific (new_ty, ty_map, struct_access (new_ty,
00522 new_ty));
00523 break;
00524
00525 case KIND_POINTER:
00526 Clear_Temp_Idx_Specific (new_ty, ty_map, pointer_access ());
00527 break;
00528
00529 case KIND_FUNCTION:
00530 Clear_Temp_Idx_Specific (new_ty, ty_map, function_access (new_ty,
00531 new_ty));
00532
00533 break;
00534 }
00535
00536 }
00537
00538
00539
00540 static TY_IDX
00541 Find_Recursive_Type (TY_INDEX index, TY_IDX_MAP& ty_map,
00542 const SYMSTR_IDX_MAP& str_map, const TY& ty)
00543 {
00544 if (!IPA_Enable_Old_Type_Merge) {
00545 if (TY_kind(ty) == KIND_STRUCT) {
00546 STR_IDX struct_name = str_map[TY_name_idx(ty)];
00547 TY_INDEX find_ty = struct_by_name_idx[struct_name];
00548
00549
00550 if (find_ty &&
00551 (TY_is_incomplete_struct(make_TY_IDX(find_ty)) || TY_is_incomplete_struct(ty)))
00552 return make_TY_IDX(find_ty);
00553 }
00554 }
00555
00556
00557
00558 TY_IDX_VEC ty_list;
00559 Find_Matching_Ty (ty, ty_list);
00560
00561 for (TY_IDX_VEC::const_iterator iter (ty_list.begin ());
00562 iter != ty_list.end (); ++iter) {
00563 VALIDATION_STATE state =
00564 Validate_Recursive_Type (index, ty_map, str_map, *iter);
00565
00566 if (state == VALIDATE_OK) {
00567 return *iter;
00568 }
00569
00570 Is_True (state != VALIDATE_COMMIT, ("Inconsistent cycles in types"));
00571
00572 Clear_All_Temp_Idx (index, ty_map);
00573 }
00574
00575 return 0;
00576 }
00577
00578
00579
00580 static void
00581 Commit_Recursive_Type (TY_INDEX index, TY_IDX_MAP& ty_map,
00582 TY_IDX merged_ty_idx);
00583 namespace
00584 {
00585
00586 template <class ACCESS>
00587 void
00588 Commit_Ty_Specific (const TY& new_ty, TY_IDX_MAP& ty_map,
00589 TY_IDX merged_ty_idx, const ACCESS& ty_node)
00590 {
00591 const TY& merged_ty = Ty_Table[merged_ty_idx];
00592 Is_True (TY_kind (merged_ty) == ty_node.kind (),
00593 ("Invalid type in Commit_Recursive_Type"));
00594
00595 UINT kid_count = ty_node.kid_count ();
00596 for (UINT i = 0; i < kid_count; ++i) {
00597 TY_INDEX kid_index = TY_IDX_index (ty_node.kid (new_ty, i));
00598 TY_IDX mapped_kid_idx = ty_map.map_[kid_index];
00599 if (! Valid_TY_IDX (mapped_kid_idx))
00600 Commit_Recursive_Type (kid_index, ty_map,
00601 ty_node.kid (merged_ty, i));
00602 }
00603 }
00604 }
00605
00606
00607
00608 static void
00609 Commit_Recursive_Type (TY_INDEX index, TY_IDX_MAP& ty_map,
00610 TY_IDX merged_ty_idx)
00611 {
00612 const TY& new_ty = file_tables->ty_tab[index];
00613
00614 if (!IPA_Enable_Old_Type_Merge) {
00615 if (TY_is_incomplete_struct(new_ty) || TY_is_incomplete_struct(merged_ty_idx)) {
00616
00617
00618 if (!TY_is_incomplete_struct(new_ty)) {
00619
00620
00621 if (IN_SET(updating_incomplete_ty, TY_IDX_index(merged_ty_idx)))
00622 TY_Init(New_TY(merged_ty_idx), 0, KIND_STRUCT, MTYPE_M, 0);
00623 to_update_incomplete_ty.insert(index);
00624 updating_incomplete_ty.insert(TY_IDX_index(merged_ty_idx));
00625 }
00626 ty_map.set_map(index, merged_ty_idx);
00627 return;
00628 }
00629 }
00630
00631 TY_IDX& my_mapped_idx = ty_map.map_[index];
00632
00633 Is_True (! Valid_TY_IDX (my_mapped_idx), ("Invalid type index"));
00634
00635 ty_map.set_map (index, merged_ty_idx);
00636
00637 switch (TY_kind (new_ty)) {
00638 case KIND_SCALAR:
00639 case KIND_VOID:
00640 return;
00641
00642 case KIND_ARRAY:
00643 Commit_Ty_Specific (new_ty, ty_map, merged_ty_idx, array_access ());
00644 break;
00645
00646 case KIND_STRUCT:
00647 Commit_Ty_Specific (new_ty, ty_map, merged_ty_idx,
00648 struct_access (new_ty, Ty_Table[merged_ty_idx]));
00649 break;
00650
00651 case KIND_POINTER:
00652 Commit_Ty_Specific (new_ty, ty_map, merged_ty_idx, pointer_access ());
00653 break;
00654
00655 case KIND_FUNCTION:
00656 Commit_Ty_Specific (new_ty, ty_map, merged_ty_idx,
00657 function_access (new_ty, Ty_Table[merged_ty_idx]));
00658 break;
00659 }
00660 }
00661
00662
00663 static TY_IDX
00664 Insert_Ty (TY_INDEX index, TY_IDX_MAP& ty_map, const SYMSTR_IDX_MAP& str_map);
00665
00666 namespace
00667 {
00668
00669 template <class ACCESS>
00670 TY_IDX
00671 Insert_Ty_Specific (TY_INDEX index, TY_IDX_MAP& ty_map,
00672 const SYMSTR_IDX_MAP& str_map, const ACCESS& ty_node)
00673 {
00674 const TY& ty = file_tables->ty_tab[index];
00675 TY_IDX& my_mapped_idx = ty_map.map_[index];
00676
00677
00678 UINT kid_count = ty_node.kid_count ();
00679 BOOL new_recursive_type = FALSE;
00680 UINT i;
00681 for (i = 0; i < kid_count; ++i ) {
00682 TY_IDX kid_idx = ty_node.kid (ty, i);
00683 TY_IDX mapped_kid_idx = ty_map.map_[TY_IDX_index (kid_idx)];
00684
00685 Is_True (! Is_TY_Temp_Idx (mapped_kid_idx),
00686 ("Overlapping insertion and validation phase"));
00687
00688 if (mapped_kid_idx == 0) {
00689 mapped_kid_idx = Insert_Ty (TY_IDX_index (kid_idx), ty_map,
00690 str_map);
00691 if (Valid_TY_IDX (my_mapped_idx)) {
00692
00693
00694 return my_mapped_idx;
00695 }
00696 } else if (TY_Inserted (mapped_kid_idx))
00697 continue;
00698
00699 if (!Valid_TY_IDX (mapped_kid_idx)) {
00700 TY_IDX original_ty_idx;
00701 Is_True (TY_Merging (mapped_kid_idx),
00702 ("Invalid state in type merging"));
00703
00704
00705 original_ty_idx = my_mapped_idx;
00706
00707
00708
00709
00710
00711 TY_IDX matched_idx = new_recursive_type ? 0 :
00712 Find_Recursive_Type (index, ty_map, str_map, ty);
00713
00714 if (matched_idx == 0) {
00715 my_mapped_idx = Replace_TY_IDX_index(my_mapped_idx, original_ty_idx);
00716 }
00717
00718 if (matched_idx == 0) {
00719
00720 TY_IDX recursive_ty_idx;
00721 (void) New_TY (recursive_ty_idx);
00722 Set_TY_Inserted (ty_map.map_[TY_IDX_index (kid_idx)],
00723 recursive_ty_idx);
00724 if (IPA_Enable_Old_Type_Merge)
00725 Initialize_New_Recursive_Type (recursive_ty_idx);
00726 } else {
00727 Is_True (Valid_TY_IDX (matched_idx), ("Invalid TY_IDX"));
00728
00729
00730 Commit_Recursive_Type (index, ty_map, matched_idx);
00731 return matched_idx;
00732 }
00733 }
00734 }
00735
00736
00737 if (TY_Inserted (my_mapped_idx)) {
00738
00739 Clean_TY_IDX (my_mapped_idx);
00740 TY& new_ty = Ty_Table[my_mapped_idx];
00741 new_ty = ty;
00742 Insert_Allocated_Ty (new_ty, my_mapped_idx);
00743 if (IPA_Enable_Old_Type_Merge) {
00744 Finalize_New_Recursive_Type ();
00745 }
00746 else {
00747 if (TY_is_incomplete_struct(my_mapped_idx))
00748 updating_incomplete_ty.insert(TY_IDX_index(my_mapped_idx));
00749 }
00750 return my_mapped_idx;
00751 } else {
00752 if (IPA_Enable_Old_Type_Merge) {
00753 return Insert_Unique_Ty (ty);
00754 }
00755 else {
00756 TY_IDX return_idx = Insert_Unique_Ty(ty);
00757 if (TY_is_incomplete_struct(return_idx))
00758 updating_incomplete_ty.insert(TY_IDX_index(return_idx));
00759 return return_idx;
00760 }
00761 }
00762 }
00763 }
00764
00765
00766 static TY_IDX
00767 Insert_Ty (TY_INDEX index, TY_IDX_MAP& ty_map, const SYMSTR_IDX_MAP& str_map)
00768 {
00769 TY_IDX& mapped_idx = ty_map.map_[index];
00770
00771 Is_True (mapped_idx == 0, ("Invalid call to Insert_Ty"));
00772
00773 Set_TY_Merging (mapped_idx);
00774
00775 const TY& ty = file_tables->ty_tab[index];
00776
00777 TY_IDX return_idx;
00778
00779 if (!IPA_Enable_Old_Type_Merge) {
00780 if (TY_kind(ty) == KIND_STRUCT) {
00781 STR_IDX struct_name = str_map[ty.name_idx];
00782 return_idx = make_TY_IDX(struct_by_name_idx[struct_name]);
00783
00784
00785 if (TY_is_incomplete_struct(ty) && return_idx > 0) {
00786 ty_map.set_map(index, return_idx);
00787 return return_idx;
00788 }
00789
00790
00791 if ((!TY_is_incomplete_struct(ty)) && return_idx > 0
00792 && TY_is_incomplete_struct(return_idx)) {
00793
00794
00795 if (IN_SET(updating_incomplete_ty, TY_IDX_index(return_idx)))
00796 TY_Init(New_TY(return_idx), 0, KIND_STRUCT, MTYPE_M, 0);
00797 ty_map.set_map(index, return_idx);
00798 to_update_incomplete_ty.insert(index);
00799 updating_incomplete_ty.insert(TY_IDX_index(return_idx));
00800 return return_idx;
00801 }
00802 }
00803 }
00804
00805 switch (TY_kind (ty)) {
00806 case KIND_SCALAR:
00807 case KIND_VOID:
00808 return_idx = Insert_Unique_Ty (ty);
00809 break;
00810
00811 case KIND_ARRAY:
00812 return_idx = Insert_Ty_Specific (index, ty_map, str_map,
00813 array_access ());
00814 break;
00815
00816 case KIND_STRUCT:
00817 return_idx = Insert_Ty_Specific (index, ty_map, str_map,
00818 struct_access (ty, ty));
00819 break;
00820
00821 case KIND_POINTER:
00822 return_idx = Insert_Ty_Specific (index, ty_map, str_map,
00823 pointer_access ());
00824 break;
00825
00826 case KIND_FUNCTION:
00827 return_idx = Insert_Ty_Specific (index, ty_map, str_map,
00828 function_access (ty, ty));
00829 break;
00830
00831 default:
00832 Fail_FmtAssertion ("Invalid TY_kind");
00833 return 0;
00834 }
00835
00836 ty_map.set_map (index, return_idx);
00837
00838 if (!IPA_Enable_Old_Type_Merge) {
00839 switch (TY_kind(return_idx)) {
00840 case KIND_POINTER:
00841
00842
00843 if (TY_align(TY_pointed(return_idx)) == 1)
00844 Set_TY_align(Ty_Table[return_idx].u2.pointed, TY_align(TY_pointed(ty)));
00845 break;
00846 case KIND_STRUCT:
00847 struct_by_name_idx[TY_name_idx(return_idx)] = TY_IDX_index(return_idx);
00848 break;
00849 }
00850 }
00851
00852 return return_idx;
00853 }
00854
00863 hash_set <TY_INDEX> complete_nonrecursive_type;
00864 hash_set <TY_INDEX> processing_recursive_type;
00865 BOOL Is_Incomplete_Or_Recursive(TY_INDEX ty_index) {
00866 if (IN_SET(complete_nonrecursive_type, ty_index))
00867 return FALSE;
00868 if (IN_SET(processing_recursive_type, ty_index))
00869 return TRUE;
00870 if (TY_is_incomplete_struct(Ty_tab[ty_index]))
00871 return TRUE;
00872
00873 processing_recursive_type.insert(ty_index);
00874
00875 BOOL result = FALSE;
00876 TY_IDX ty_idx = make_TY_IDX(ty_index);
00877 FLD_HANDLE fld;
00878 FLD_ITER fld_iter;
00879 TYLIST_ITER tylist_iter;
00880 switch (TY_kind(ty_idx)) {
00881 case KIND_STRUCT:
00882 if (Ty_tab[ty_index].Fld() == 0)
00883 break;
00884 fld = TY_fld(ty_idx);
00885 fld_iter = Make_fld_iter(fld);
00886 do {
00887 if (Is_Incomplete_Or_Recursive(TY_IDX_index(FLD_type(fld)))) {
00888 result = TRUE;
00889 break;
00890 }
00891 if (FLD_last_field(fld))
00892 break;
00893 ++fld_iter;
00894 fld = fld_iter;
00895 } while (1);
00896 break;
00897 case KIND_POINTER:
00898 result = Is_Incomplete_Or_Recursive(TY_IDX_index(TY_pointed(ty_idx)));
00899 break;
00900 case KIND_FUNCTION:
00901 tylist_iter = Make_tylist_iter(TY_tylist(ty_idx));
00902 while (*tylist_iter != 0) {
00903 if (Is_Incomplete_Or_Recursive(TY_IDX_index(*tylist_iter))) {
00904 result = TRUE;
00905 break;
00906 }
00907 ++tylist_iter;
00908 }
00909 break;
00910 case KIND_ARRAY:
00911 result = Is_Incomplete_Or_Recursive(TY_IDX_index(TY_etype(ty_idx)));
00912 break;
00913 }
00914 processing_recursive_type.erase(ty_index);
00915 if (!result)
00916 complete_nonrecursive_type.insert(ty_index);
00917 return result;
00918 }
00919
00920 void
00921 Merge_All_Types (const IPC_GLOBAL_TABS& original_tabs,
00922 IPC_GLOBAL_IDX_MAP& idx_map)
00923 {
00924 Temporary_Error_Phase ephase ("IPA Type Merging");
00925
00926 Setup_Type_Merging_Hash_Tables (original_tabs, idx_map);
00927
00928 file_tables = &original_tabs;
00929 TY_IDX_MAP& ty_map = idx_map.ty;
00930 const SYMSTR_IDX_MAP& str_map = idx_map.sym_str;
00931
00932 if (!IPA_Enable_Old_Type_Merge) {
00933 to_update_incomplete_ty.clear();
00934 updating_incomplete_ty.clear();
00935 }
00936
00937 for (UINT idx = 1; idx < file_tables->ty_tab_size; ++idx) {
00938 if (ty_map.map_[idx] == 0)
00939 (void) Insert_Ty (idx, ty_map, str_map);
00940 else
00941 Is_True (Valid_TY_IDX (ty_map.map_[idx]), ("Invalid TY_IDX"));
00942 }
00943
00944 if (!IPA_Enable_Old_Type_Merge) {
00945
00946 for (hash_set <TY_INDEX>::iterator iter = to_update_incomplete_ty.begin();
00947 iter != to_update_incomplete_ty.end(); iter++) {
00948 TY_INDEX new_ty_idx = *iter;
00949 TY_IDX merged_ty_idx = ty_map.map_[new_ty_idx];
00950 if (TY_is_incomplete_struct(merged_ty_idx)) {
00951 TY &new_ty = Ty_Table[merged_ty_idx];
00952 new_ty = file_tables->ty_tab[new_ty_idx];
00953 Insert_Allocated_Ty(new_ty, merged_ty_idx);
00954 }
00955 ty_map.set_map(new_ty_idx, merged_ty_idx);
00956 }
00957 for (UINT idx = 1; idx < file_tables->ty_tab_size; ++idx)
00958
00959
00960 if (Is_Incomplete_Or_Recursive(TY_IDX_index(ty_map.map_[idx])))
00961 Insert_Recursive_Type(ty_map.map_[idx]);
00962 }
00963 }
00964