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
00041
00042
00043
00044
00045
00046
00047 #define __STDC_LIMIT_MACROS
00048 #include <stdint.h>
00049 #include <vector>
00050 #include <stack>
00051 #include <algorithm>
00052 #include <list>
00053 #include <map>
00054 #include <math.h>
00055
00056 #include "defs.h"
00057 #include "tracing.h"
00058 #include "ipa_trace.h"
00059 #include <search.h>
00060 #include <memory.h>
00061 #include "wn_util.h"
00062 #include "cxx_template.h"
00063 #include "wn_core.h"
00064 #include "mempool.h"
00065 #include "ipa_cg.h"
00066 #include "ipa_reorder.h"
00067 #include "ir_reader.h"
00068 #ifdef KEY
00069 #include "ipo_parent.h"
00070 #endif // KEY
00071
00072 typedef hash_map<mUINT32,CAND_ITEM*> TY_TO_CAND_MAP;
00073 struct PTR_AND_TY
00074 {
00075 mUINT32 ty_index;
00076 mUINT32 pt_index;
00077 };
00078 typedef vector<struct PTR_AND_TY> PTR_AND_TY_VECTOR;
00079 extern TY_TO_CAND_MAP Ty_to_cand_map;
00080
00081 REORDER_CAND reorder_candidate;
00082 TYPE_LIST can_be_reordered_types;
00083 TYPE_LIST invalid_reorder_types;
00084
00085 TY_TO_CAND_MAP Ty_to_cand_map;
00086 PTR_AND_TY_VECTOR *Ptr_and_ty_vector;
00087
00088
00089
00090 MERGED_ACCESS_VECTOR *merged_access;
00091 MEM_POOL reorder_local_pool;
00092 typedef hash_map<mUINT32,MERGED_ACCESS*> TY_TO_ACCESS_MAP;
00093 TY_TO_ACCESS_MAP *ty_to_access_map;
00094 BOOL* visited;
00095 inline TY_IDX
00096 TY_POINT_TO_NON_UNIONSTRUCT(TY &ty)
00097 {
00098 TY_IDX ret;
00099 ret=0;
00100 if(ty.kind==KIND_POINTER){
00101 TY_IDX point_to_ty=TY_pointed(ty);
00102 TY* cur_ty=&Ty_Table[point_to_ty];
00103 if(cur_ty->kind==KIND_STRUCT&& !((cur_ty->flags)&TY_IS_UNION))
00104 return point_to_ty;
00105 }
00106 return ret;
00107 }
00108
00109
00110
00111
00112
00113 void Init_merge_access()
00114 {
00115 MEM_POOL_Initialize(&reorder_local_pool,"reorder_pool",TRUE);
00116 MEM_POOL_Push (&reorder_local_pool);
00117 merged_access=CXX_NEW(vector< MERGED_ACCESS*>,&reorder_local_pool);
00118 ty_to_access_map=CXX_NEW(TY_TO_ACCESS_MAP(),&reorder_local_pool);
00119 Ptr_and_ty_vector=CXX_NEW(PTR_AND_TY_VECTOR(),&reorder_local_pool);
00120 reorder_candidate.size=0;
00121 reorder_candidate.list=NULL;
00122
00123 }
00124 void print_merged_access()
00125 {
00126 MERGED_ACCESS_VECTOR::iterator iter;
00127 MERGED_ACCESS *cur_access;
00128 INDEX index,i;
00129 INDEX size=merged_access->size();
00130 fprintf(TFile,"STRUCT ACCESS: after merge:%d\n",size);
00131 for(iter=merged_access->begin();iter!=merged_access->end();iter++){
00132 cur_access=(*iter);
00133 index=cur_access->ty_index;
00134 fprintf(TFile,"\n type(%s)\n",Index_To_Str(Ty_tab[index].name_idx));
00135 for(i=0;i<cur_access->flatten_fields;i++){
00136 fprintf(TFile,"[%d]=%lld",i,cur_access->count[i]);
00137 if ((i+1)% 8==0)
00138 fprintf(TFile,"\n");
00139
00140 }
00141 }
00142 fprintf(TFile,"\n");
00143 FmtAssert(size<=ty_to_access_map->size(),
00144 ("merged_access size <=ty_to_access_map!\n"));
00145 return;
00146 }
00147
00148
00149
00150
00151 void Merge_struct_access(SUMMARY_STRUCT_ACCESS *cur_summary, mUINT32 index)
00152 {
00153 FIELD_ID fld_id,flatten_flds;
00154 COUNT count;
00155 MERGED_ACCESS *cur_access;
00156 TY_TO_ACCESS_MAP::iterator iter;
00157 BOOL Trace_it=Get_Trace ( TP_IPA,IPA_TRACE_TUNING_NEW );
00158 if ( Trace_it)
00159 fprintf(TFile,"merging...!\n");
00160 flatten_flds=cur_summary->Get_flatten_flds();
00161 iter=ty_to_access_map->find(index);
00162 if(iter!=ty_to_access_map->end())
00163 cur_access=iter->second;
00164 else{
00165 cur_access = (MERGED_ACCESS*)MEM_POOL_Alloc_P(&reorder_local_pool,
00166 sizeof(MERGED_ACCESS),TRUE,NULL);
00167
00168 cur_access->ty_index=index;
00169 cur_access->flatten_fields=flatten_flds;
00170
00171 cur_access->count = (mUINT64*)MEM_POOL_Alloc_P(&reorder_local_pool,
00172 sizeof(mUINT64)*flatten_flds,TRUE,NULL);
00173
00174 merged_access->push_back(cur_access);
00175 ty_to_access_map->insert(make_pair(index,cur_access));
00176
00177 }
00178 FmtAssert(index==cur_access->ty_index,
00179 ("index is consistent, find is wrong!\n"));
00180 for(INT i=0;i<8;i++)
00181 {
00182 fld_id=cur_summary->Get_hot_fld_id(i);
00183 if(!fld_id) break;
00184 count=cur_summary->Get_hot_fld(i);
00185 cur_access->count[fld_id-1]+=count;
00186 }
00187 if (Trace_it)
00188 print_merged_access();
00189 return;
00190 }
00191
00192
00193
00194
00195
00196
00197 MERGED_ACCESS* find_merged_access(INDEX ty_index)
00198
00199 {
00200 MERGED_ACCESS_VECTOR::iterator iter;
00201 MERGED_ACCESS* cur_access;
00202 MERGED_ACCESS* found_access=NULL;
00203 for(iter=merged_access->begin();
00204 iter!=merged_access->end();
00205 iter++)
00206 {
00207 cur_access=*iter;
00208 if(ty_index==cur_access->ty_index){
00209 found_access=cur_access;
00210 break;
00211 }
00212 }
00213 return found_access;
00214 }
00215
00216 struct TOP_FIELD_INFO{
00217 FIELD_ID field_id;
00218 TY_IDX ty_idx;
00219 TY_SIZE size;
00220 #ifdef KEY
00221 mUINT32 align;
00222 #endif // KEY
00223 };
00224
00225 typedef list<TOP_FIELD_INFO> TOP_FLD_LIST;
00226 struct TOP_FLD_DESC{
00227 TY_SIZE size;
00228 TOP_FLD_LIST list;
00229 };
00230
00231
00232
00233
00234
00235 CAND_ITEM* find_in_reorder_candidate(INDEX ty_index)
00236 {
00237 INDEX i;
00238 CAND_ITEM *found=NULL;
00239 CAND_ITEM *cur_cand;
00240 cur_cand=reorder_candidate.list;
00241 for(i=0;i<reorder_candidate.size;i++,cur_cand++)
00242 {
00243 if(cur_cand->ty_index==ty_index){
00244 found=cur_cand;
00245 break;
00246 }
00247 }
00248 return found;
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 mUINT64 Handle_access_count(INDEX ty_index, TOP_FLD_DESC& idlist,
00261 FIELD_ID &field_id, CAND_ITEM* p_cand)
00262 {
00263
00264 FLD_IDX start_fld_idx;
00265 TOP_FIELD_INFO top_field;
00266 BOOL is_struct;
00267 BOOL in_enclosed_struct=FALSE;
00268 CAND_ITEM* sub_cand=NULL;
00269 mUINT64 sum,sub_sum,this_count,local_sum;
00270 INDEX sub_fld_id,i;
00271 FIELD_ID pre_field_id,j;
00272 sum=0;
00273 if(p_cand->ty_index!=ty_index){
00274 in_enclosed_struct=TRUE;
00275 p_cand->flag.has_enclosed_struct=TRUE;
00276 sub_cand=find_in_reorder_candidate(ty_index);
00277 }
00278
00279 for(i=0,start_fld_idx=Ty_tab[ty_index].u1.fld;;
00280 i++,start_fld_idx++){
00281 field_id++;
00282 TY_IDX cur_idx= Fld_Table[start_fld_idx].type;
00283 TY*cur_ty=& Ty_Table[cur_idx];
00284 char *ty_name=Index_To_Str(cur_ty->name_idx);
00285 if(cur_ty->kind==KIND_STRUCT){
00286 is_struct=TRUE;
00287 }else
00288 is_struct=FALSE;
00289
00290 if(!in_enclosed_struct){
00291 idlist.size++;
00292 top_field.field_id=field_id;
00293 top_field.size=cur_ty->size;
00294 #ifdef KEY
00295 if( is_struct)
00296 top_field.ty_idx=cur_idx;
00297 else
00298 top_field.ty_idx=0;
00299 top_field.align = TY_align (cur_idx);
00300 #else
00301 if( is_struct)
00302 top_field.ty_idx=cur_idx;
00303 else
00304 top_field.ty_idx=0;
00305 #endif // KEY
00306 idlist.list.push_back(top_field);
00307 }else{
00308 this_count=p_cand->fld_info.map[field_id-1].count;
00309 sum+=this_count;
00310
00311 #ifdef KEY
00312
00313
00314 if (sub_cand && sub_cand->top_field_info.list) {
00315 #else
00316 if(sub_cand){
00317 #endif // KEY
00318 sub_fld_id=sub_cand->top_field_info.list[i].field_id;
00319 sub_cand->fld_info.map[sub_fld_id-1].count+=this_count;
00320 }
00321 }
00322 if( is_struct){
00323 pre_field_id=field_id;
00324 sub_sum=Handle_access_count(cur_idx>>8,idlist,field_id,p_cand);
00325 local_sum=p_cand->fld_info.map[pre_field_id-1].count+sub_sum;
00326 for(j=pre_field_id;j<=field_id;j++)
00327 p_cand->fld_info.map[j-1].count=local_sum;
00328 if(in_enclosed_struct)
00329 sum+=sub_sum;
00330 }
00331 if(Fld_Table[start_fld_idx].flags & FLD_LAST_FIELD)
00332 break;
00333 }
00334 return sum;
00335 }
00336
00337
00338 void check_reorder_legality_of_type(INDEX ty_index);
00339
00340
00341
00342
00343
00344 BOOL find_in_invalid_types(INDEX ty_index)
00345
00346 {
00347 TYPE_LIST::iterator iter;
00348 BOOL found=FALSE;
00349 for(iter=invalid_reorder_types.begin();iter!=invalid_reorder_types.end();iter++)
00350 {
00351 if(ty_index==*iter){
00352 found=TRUE;
00353 break;
00354 }
00355 }
00356 return found;
00357 }
00358
00359
00360
00361
00362 void invalidate_it(INDEX ty_index)
00363 {
00364 visited[ty_index]=TRUE;
00365 if(!find_in_invalid_types(ty_index)){
00366 invalid_reorder_types.push_back(ty_index);
00367 can_be_reordered_types.remove(ty_index);
00368 }
00369 TY *ty=&Ty_tab[ty_index];
00370 for(UINT cur_fld_idx=ty->u1.fld;;cur_fld_idx++){
00371 FLD & cur_fld=Fld_Table[cur_fld_idx];
00372 TY* cur_fld_ty=&Ty_Table[cur_fld.type];
00373 UINT flags=cur_fld.flags;
00374 if(cur_fld_ty->kind==KIND_STRUCT){
00375 invalidate_it(cur_fld.type>>8);
00376 }
00377 if(cur_fld.flags & FLD_LAST_FIELD)
00378 break;
00379 }
00380 return;
00381 }
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395 void get_can_be_reordered_types()
00396 {
00397 TY_TAB::iterator iter;
00398 BOOL propagate;
00399 INDEX point_to;
00400 BOOL Trace_it=Get_Trace ( TP_IPA,IPA_TRACE_TUNING_NEW );
00401 MEM_POOL_Push (&reorder_local_pool);
00402 mUINT64 size=Ty_tab.size();
00403 visited = (BOOL*)MEM_POOL_Alloc_P(&reorder_local_pool,sizeof(BOOL)*size,TRUE,NULL);
00404 memset(visited,0,sizeof(BOOL)*size);
00405 if (Trace_it)
00406 fprintf(TFile,"in get_can_be_reordered_types\n");
00407 for(iter=Ty_tab.begin();iter!=Ty_tab.end();iter++)
00408 {
00409 if((*iter).kind==KIND_STRUCT){
00410 propagate=FALSE;
00411 check_reorder_legality_of_type(iter.Index());
00412 }
00413 else if(point_to=TY_POINT_TO_NON_UNIONSTRUCT(*iter)>>8){
00414
00415 INDEX ty_index=iter.Index();
00416 PTR_AND_TY item;
00417 item.ty_index=ty_index;
00418 item.pt_index=point_to;
00419 Ptr_and_ty_vector->push_back(item);
00420 }
00421 }
00422 if (Trace_it)
00423 fprintf(TFile, "invalid-reorder_types' size=%d! \n", (INT)invalid_reorder_types.size());
00424 MEM_POOL_Pop (&reorder_local_pool);
00425 return;
00426 }
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450 void check_reorder_legality_of_type(INDEX ty_index)
00451 {
00452 TYPE_LIST::iterator iter;
00453 BOOL found, legal;
00454 BOOL invalidate=FALSE;
00455 TYPE_LIST low_level_tys;
00456 TY* ty=&Ty_tab[ty_index];
00457 if (visited[ty_index])
00458 return;
00459 FmtAssert(ty->kind==KIND_STRUCT,("the checked type must be STRUCT"));
00460 #ifdef KEY
00461 if (!ty->size || !ty->u1.fld)
00462 {
00463
00464
00465
00466
00467
00468 visited[ty_index] = TRUE;
00469 return;
00470 }
00471 if ((ty->size <= 56) || (ty->size > 60))
00472 {
00473 visited[ty_index] = TRUE;
00474 return;
00475 }
00476 #endif // KEY
00477 if (ty->flags &TY_IS_UNION)
00478 invalidate=TRUE;
00479
00480 for(UINT cur_fld_idx=ty->u1.fld;;cur_fld_idx++){
00481 FLD & cur_fld=Fld_Table[cur_fld_idx];
00482 TY* cur_fld_ty=&Ty_Table[cur_fld.type];
00483 mUINT16 flags=cur_fld.flags;
00484 if((flags & FLD_IS_BIT_FIELD)||(flags&FLD_BEGIN_UNION)){
00485
00486 invalidate=TRUE;
00487 break;
00488 }
00489 if(cur_fld_ty->kind==KIND_STRUCT){
00490
00491 INDEX sub_index=cur_fld.type>>8;
00492 low_level_tys.remove(sub_index);
00493 low_level_tys.push_back(sub_index);
00494 }
00495 if(cur_fld.flags & FLD_LAST_FIELD)
00496 break;
00497 }
00498
00499 if(invalidate){
00500 invalid_reorder_types.push_back(ty_index);
00501 for (iter=low_level_tys.begin();iter!=low_level_tys.end();iter++)
00502
00503 if(!find_in_invalid_types(*iter))
00504 invalidate_it(*iter);
00505 }
00506 else{
00507 #ifndef KEY
00508
00509
00510 for (iter=low_level_tys.begin();iter!=low_level_tys.end();iter++)
00511 check_reorder_legality_of_type(*iter);
00512 #endif // !KEY
00513 if(!visited[ty_index])
00514 can_be_reordered_types.push_back(ty_index);
00515 }
00516 low_level_tys.clear();
00517 visited[ty_index]=TRUE;
00518 return;
00519 }
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537 void check_gsymbol_for_invalid_type()
00538 {
00539 TYPE_LIST::iterator ty_iter;
00540 PU_IDX cur_pu;
00541 TY_IDX cur_ty_idx,prototype;
00542 TYLIST tylist;
00543 BOOL found;
00544 ST_IDX i;
00545
00546
00547 for (i = 1; i < ST_Table_Size(GLOBAL_SYMTAB); ++i) {
00548 ST* cur_st = &St_Table(GLOBAL_SYMTAB,i);
00549 INDEX ty_index=cur_st->u2.type>>8;
00550 if(Ty_tab[ty_index].kind==KIND_STRUCT){
00551 if(ST_addr_saved (cur_st) || ST_addr_passed (cur_st))
00552 invalidate_it(ty_index);
00553 else if(ST_is_weak_symbol(*cur_st))
00554 invalidate_it(ty_index);
00555 }
00556 #ifdef KEY
00557 else if (Ty_tab[ty_index].kind == KIND_POINTER) {
00558 INDEX pointed = TY_pointed (Ty_tab[ty_index]) >> 8;
00559 if (Ty_tab[pointed].kind == KIND_STRUCT)
00560 invalidate_it (pointed);
00561 }
00562 #endif // KEY
00563 else if(cur_st->sym_class == CLASS_FUNC
00564 ||(cur_st->sym_class == CLASS_NAME
00565 &&(cur_st->flags & ST_ASM_FUNCTION_ST)))
00566 {
00567 PU_IDX pu;
00568 IPA_NODE* node;
00569 pu=ST_pu(cur_st);
00570
00571 found=FALSE;
00572 IPA_NODE_ITER cg_iter(IPA_Call_Graph, PREORDER);
00573 for (cg_iter.First(); !cg_iter.Is_Empty(); cg_iter.Next()) {
00574 node = cg_iter.Current();
00575 if (node) {
00576 if(node->Func_ST()==cur_st){
00577 found=TRUE;
00578 break;
00579 }
00580 }
00581 }
00582 if(found)
00583 continue;
00584
00585
00586 tylist=Ty_Table[Pu_Table[pu].prototype].u1.tylist;
00587
00588 while(cur_ty_idx=Tylist_Table[tylist]){
00589 TY* cur_ty=&Ty_Table[cur_ty_idx];
00590 TY_KIND kinds=cur_ty->kind;
00591 INDEX index;
00592 if(cur_ty->kind==KIND_STRUCT&& !((cur_ty->flags)&TY_IS_UNION)){
00593 if ( Get_Trace ( TP_IPA,IPA_TRACE_TUNING_NEW ) )
00594 fprintf(TFile, "a invalid STRUCT %s ! \n",
00595 Index_To_Str(cur_ty->name_idx) );
00596 index=cur_ty_idx>>8;
00597 if(!find_in_invalid_types(index)){
00598 invalidate_it(index);
00599 }
00600 }
00601 else if(kinds==KIND_POINTER){
00602 TY_IDX point_to_ty=TY_pointed(cur_ty_idx);
00603 TY* cur_ty=&Ty_Table[point_to_ty];
00604 if(cur_ty->kind==KIND_STRUCT&& !((cur_ty->flags)&TY_IS_UNION)){
00605 index=point_to_ty>>8;
00606 if(!find_in_invalid_types(index)){
00607 invalidate_it(index);
00608 if ( Get_Trace ( TP_IPA,IPA_TRACE_TUNING_NEW ) )
00609 fprintf(TFile, "a invalid POINT_TO_STRUCT %s ! \n",
00610 Index_To_Str(cur_ty->name_idx) );
00611 }
00612 }
00613 }
00614 else if(kinds==KIND_ARRAY){
00615 TY_IDX base_ty=cur_ty->u2.etype;
00616 TY* cur_ty=&Ty_Table[base_ty];
00617 if(cur_ty->kind==KIND_STRUCT&& !((cur_ty->flags)&TY_IS_UNION)){
00618 index=base_ty>>8;
00619 if(!find_in_invalid_types(index)){
00620 if ( Get_Trace ( TP_IPA,IPA_TRACE_TUNING_NEW ) )
00621 fprintf(TFile, "a invalid ARRAY_TO_STRUCT %s ! \n",
00622 Index_To_Str(cur_ty->name_idx) );
00623 invalidate_it(index);
00624 }
00625 }
00626 }
00627 tylist++;
00628 }
00629 }
00630 }
00631 return;
00632 }
00633 void print_invalid_and_valid_type()
00634 {
00635 TYPE_LIST::iterator iter;
00636 INDEX i;
00637 fprintf(TFile," invalid reorder types: ( size=%d)\n", (INT)invalid_reorder_types.size());
00638 for(i=1,iter=invalid_reorder_types.begin();
00639 iter!=invalid_reorder_types.end();i++,iter++)
00640 {
00641 TY& ty=Ty_tab[*iter];
00642 fprintf(TFile,"<%5d,%-10s>",*iter,Index_To_Str(ty.name_idx));
00643 if(i %4==0) fprintf(TFile,"\n");
00644 }
00645 fprintf(TFile,"\n");
00646 fprintf(TFile," valid reorder types: (size=%d)\n",
00647 (INT)can_be_reordered_types.size());
00648 for(i=1, iter=can_be_reordered_types.begin();
00649 iter!=can_be_reordered_types.end();
00650 i++, iter++)
00651 {
00652 TY& ty=Ty_tab[*iter];
00653 fprintf(TFile,"<%5d,%-10s>",*iter,Index_To_Str(ty.name_idx));
00654 if(i%4==0)
00655 fprintf(TFile,"\n");
00656 }
00657 fprintf(TFile,"\n");
00658 return;
00659 }
00660 void Print_field_access_info()
00661 {
00662 TY_SIZE size,struct_size;
00663 TYPE_LIST::iterator iter;
00664 CAND_ITEM* p_cand;
00665 size=reorder_candidate.size;
00666 p_cand=reorder_candidate.list;
00667
00668 fprintf(TFile,"reorder_candidate:<type name, flatten_fields, enclosed_struct>\n");
00669 for(UINT i=0;i<size;p_cand++,i++)
00670 {
00671 TY& ty=Ty_tab[p_cand->ty_index];
00672 struct_size=p_cand->fld_info.flatten_fields;
00673 fprintf(TFile,"<%-10s, %6lld, %2d>\n",
00674 Index_To_Str(ty.name_idx),
00675 struct_size,
00676 p_cand->flag.has_enclosed_struct);
00677 fprintf(TFile," fld count=(");
00678 for(UINT j=0;j<struct_size; j++){
00679 fprintf(TFile,"%10lld-",p_cand->fld_info.map[j].count);
00680 if(j%8==0 && j)
00681 fprintf(TFile,"\n");
00682 }
00683
00684 fprintf(TFile,")\n");
00685 }
00686 }
00687
00688
00689
00690
00691
00692
00693
00694 struct Handle_ty_map_and_flatten_fields{
00695 private:
00696 FIELD_ID _field_id;
00697 INDEX _ty_index;
00698 FLD_ACCESS* _this_map;
00699 typedef list<FLD_ACCESS> MAP_LIST;
00700 MAP_LIST _map_list;
00701 MEM_POOL *_m;
00702
00703 void Get_original_map_list(INDEX ty_index,mUINT64 cur_offset){
00704 FLD_ACCESS this_fld_map;
00705 TY *ty=&Ty_tab[ty_index];
00706 for(FLD_IDX cur_fld_idx=ty->u1.fld;;cur_fld_idx++){
00707 _field_id++;
00708 this_fld_map.new_field_id=_field_id;
00709 FLD & cur_fld=Fld_Table[cur_fld_idx];
00710 TY* cur_fld_ty=&Ty_Table[cur_fld.type];
00711 mUINT16 flags=cur_fld.flags;
00712 if (cur_fld.flags& FLD_IS_BIT_FIELD)
00713 this_fld_map.offset =cur_offset+cur_fld.bofst;
00714 else
00715 this_fld_map.offset=cur_offset+cur_fld.ofst;
00716 _map_list.push_back(this_fld_map);
00717 if(cur_fld_ty->kind==KIND_STRUCT){
00718 Get_original_map_list(cur_fld.type>>8,this_fld_map.offset);
00719 }
00720 if(cur_fld.flags & FLD_LAST_FIELD)
00721 break;
00722 }
00723 return;
00724 };
00725
00726 void Count_flatten_fields(INDEX ty_index)
00727 {
00728
00729 FLD_IDX start_fld_idx=Ty_tab[ty_index].u1.fld;
00730 for(;;start_fld_idx++){
00731 _field_id++;
00732 TY_IDX cur_idx= Fld_Table[start_fld_idx].type;
00733 TY*cur_ty=& Ty_Table[cur_idx];
00734 if(cur_ty->kind==KIND_STRUCT)
00735 Count_flatten_fields( cur_idx>>8);
00736 if(Fld_Table[start_fld_idx].flags & FLD_LAST_FIELD)
00737 break;
00738 }
00739 return ;
00740 };
00741 public:
00742 Handle_ty_map_and_flatten_fields
00743 (MEM_POOL *m,INDEX ty_index) {
00744 _m=m;
00745 _field_id=0;
00746 _ty_index=ty_index;
00747 };
00748 FLD_ACCESS *Get_unaltered_map(){
00749 MAP_LIST::iterator iter;
00750 UINT i ;
00751 Get_original_map_list(_ty_index,0);
00752 mUINT16 size=_map_list.size();
00753 _this_map=(FLD_ACCESS*)MEM_POOL_Alloc_P(_m,
00754 sizeof(FLD_ACCESS)*size,TRUE,NULL);
00755 for(iter=_map_list.begin(),i=0; iter!=_map_list.end();iter++,i++){
00756 _this_map[i].new_field_id=iter->new_field_id;
00757 _this_map[i].offset=iter->offset;
00758 }
00759 return _this_map;
00760 };
00761 FIELD_ID Get_flatten_fields() {
00762 if(!_field_id)
00763 Count_flatten_fields(_ty_index);
00764 return _field_id;
00765 };
00766 };
00767
00768 #ifdef KEY
00769
00770 INT
00771 Cmp_NAME_IDX(const void *p1,const void*p2)
00772 {
00773 STR_IDX t1, t2;
00774 t1= Ty_tab [((CAND_ITEM*)p1)->ty_index].name_idx;
00775 t2= Ty_tab [((CAND_ITEM*)p2)->ty_index].name_idx;
00776 if (t1 < t2)
00777 return -1;
00778 else if (t1 > t2)
00779 return 1;
00780 else
00781 return 0;
00782 }
00783
00784 static void
00785 handle_duplicates (void)
00786 {
00787
00788 bool Trace_it=Get_Trace ( TP_IPA,IPA_TRACE_TUNING_NEW );
00789 qsort (reorder_candidate.list, reorder_candidate.size, sizeof(CAND_ITEM),
00790 Cmp_NAME_IDX);
00791
00792 CAND_ITEM *p_cand, *prev_p_cand, *start=NULL, *end=NULL;
00793 int i;
00794 for (i=0, p_cand = reorder_candidate.list; i<reorder_candidate.size;
00795 ++i, ++p_cand)
00796 {
00797 INDEX ind = p_cand->ty_index;
00798 INDEX prev_ind;
00799 TY *t1, *t2;
00800
00801 if (i)
00802 {
00803 prev_ind = prev_p_cand->ty_index;
00804 t1 = &Ty_tab[prev_ind];
00805 t2 = &Ty_tab[ind];
00806
00807 }
00808 if (i && t1->name_idx == t2->name_idx)
00809 {
00810 if (!start) start = prev_p_cand;
00811
00812 if (i == (reorder_candidate.size-1))
00813 {
00814 FmtAssert (!end, ("Reorder list processing error"));
00815 end = p_cand;
00816
00817 for (CAND_ITEM* j=start; j<=end; ++j)
00818 for (int k=0; k<j->fld_info.flatten_fields; ++k)
00819 j->fld_info.map[k].count = 0;
00820 }
00821 }
00822 else if (start)
00823 {
00824 FmtAssert (!end, ("Reorder list processing error"));
00825 end = prev_p_cand;
00826
00827
00828
00829 for (CAND_ITEM* j=start; j<=end; ++j)
00830 for (int k=0; k<j->fld_info.flatten_fields; ++k)
00831 j->fld_info.map[k].count = 0;
00832
00833 start = end = NULL;
00834 }
00835 else
00836 {
00837 prev_p_cand = p_cand;
00838 continue;
00839 }
00840
00841 prev_p_cand = p_cand;
00842 }
00843
00844 if (Trace_it)
00845 {
00846 fprintf (TFile, "After sorting and deleting duplicates\n");
00847 for (int i=0; i<reorder_candidate.size; ++i)
00848 fprintf (TFile, "%lld\n", Ty_tab[(reorder_candidate.list+i)->ty_index].name_idx);
00849 }
00850 }
00851
00852 #endif // KEY
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875 void IPA_reorder_legality_process()
00876 {
00877 INDEX size,ii,i,j,ty_num,cur_struct;
00878 TYPE_LIST::iterator iter;
00879 CAND_ITEM *p_cand,*sub_cand;
00880 TOP_FLD_DESC idlist;
00881 TOP_FLD_LIST ::iterator id_iter;
00882 FLD_ACCESS * this_map;
00883 BOOL Trace_it;
00884 FIELD_ID pre_id,cnt, flatten_flds;
00885 INDEX index, pre_ty_index;
00886 COUNT sum_count;
00887 MERGED_ACCESS* cur_merge;
00888
00889 get_can_be_reordered_types();
00890 check_gsymbol_for_invalid_type();
00891 Trace_it=Get_Trace ( TP_IPA,IPA_TRACE_TUNING_NEW );
00892 if ( Trace_it)
00893 print_invalid_and_valid_type();
00894 size=can_be_reordered_types.size();
00895 reorder_candidate.size=size;
00896 if(size)
00897 reorder_candidate.list = (CAND_ITEM*)MEM_POOL_Alloc_P(&reorder_local_pool,
00898 sizeof(CAND_ITEM)*size,TRUE,NULL);
00899 for(iter=can_be_reordered_types.begin(), p_cand=reorder_candidate.list;
00900 iter!=can_be_reordered_types.end();
00901 iter++, p_cand++)
00902 {
00903 cur_struct=*iter;
00904 p_cand->ty_index=cur_struct;
00905 strcpy(p_cand->ty_name,Index_To_Str(Ty_tab[cur_struct].name_idx));
00906
00907 cur_merge=find_merged_access(cur_struct);
00908
00909
00910 p_cand->flag.changed=FALSE;
00911 p_cand->top_field_info.size=0;
00912 Handle_ty_map_and_flatten_fields handle_ty(&reorder_local_pool,cur_struct);
00913 if(cur_merge)
00914 flatten_flds=cur_merge->flatten_fields;
00915 else{
00916 flatten_flds=handle_ty.Get_flatten_fields();
00917 }
00918 p_cand->fld_info.flatten_fields=flatten_flds;
00919 p_cand->flag.changed=FALSE;
00920 p_cand->top_field_info.size=0;
00921 p_cand->fld_info.map= (FLD_ACCESS*)MEM_POOL_Alloc_P(&reorder_local_pool,
00922 sizeof(FLD_ACCESS)*flatten_flds,TRUE,NULL);
00923 memset(p_cand->fld_info.map,0,sizeof(FLD_ACCESS)*flatten_flds);
00924
00925 this_map=p_cand->fld_info.map;
00926 #ifdef KEY
00927 FLD_ACCESS * get_old_ofst = handle_ty.Get_unaltered_map();
00928 #endif // KEY
00929 for(i=0;i<flatten_flds;i++){
00930 if(cur_merge)
00931 this_map[i].count=cur_merge->count[i];
00932 this_map[i].old_field_id=i+1;
00933 this_map[i].offset=0;
00934 #ifdef KEY
00935 this_map[i].old_offset = get_old_ofst[i].offset;
00936 #endif // KEY
00937 }
00938 }
00939 #ifdef KEY
00940
00941
00942
00943 handle_duplicates ();
00944 #endif // KEY
00945 for(cnt=1,p_cand=reorder_candidate.list;cnt<=size;
00946 p_cand++,cnt++) {
00947 cur_struct=p_cand->ty_index;
00948 this_map=p_cand->fld_info.map;
00949 flatten_flds=0;
00950 idlist.size=0;
00951
00952 Handle_access_count(cur_struct, idlist, flatten_flds, p_cand);
00953 p_cand->top_field_info.size=idlist.size;
00954 p_cand->top_field_info.list= (TOP_FIELD*)MEM_POOL_Alloc_P(&reorder_local_pool,
00955 sizeof(TOP_FIELD)*p_cand->top_field_info.size,
00956 TRUE,NULL);
00957 UINT i=0;
00958 pre_id=0;
00959 pre_ty_index=0;
00960 sum_count=0;
00961 flatten_flds=p_cand->fld_info.flatten_fields;
00962 for(id_iter=idlist.list.begin();id_iter!=idlist.list.end();i++,id_iter++){
00963 mUINT16 field_id=id_iter->field_id;
00964 mUINT64 size=id_iter->size;
00965 p_cand->top_field_info.list[i].field_id=field_id;
00966 p_cand->top_field_info.list[i].ty_idx=id_iter->ty_idx;
00967 p_cand->fld_info.map[field_id-1].offset=size;
00968 #ifdef KEY
00969 p_cand->fld_info.map[field_id-1].align=id_iter->align;
00970 #endif // KEY
00971 pre_ty_index=id_iter->ty_idx>>8;
00972 pre_id=field_id;
00973 }
00974 idlist.list.clear();
00975 }
00976 if (Trace_it )
00977 Print_field_access_info();
00978 return;
00979 }
00980
00981
00982 INT
00983 Cmp_FLD_ACCESS(const void *p1,const void*p2)
00984 {
00985 FLD_ACCESS* t1,*t2;
00986 t1=(FLD_ACCESS*)p1;
00987 t2=(FLD_ACCESS*)p2;
00988 if ( t1->count <t2->count )
00989 return 1;
00990 else if ( t1->count >t2->count )
00991 return -1;
00992 else
00993 return 0;
00994 }
00995 INT
00996 Cmp_old_field_id(const void *p1,const void*p2)
00997 {
00998 FLD_ACCESS* t1,*t2;
00999 t1=(FLD_ACCESS*)p1;
01000 t2=(FLD_ACCESS*)p2;
01001 if ( t1->old_field_id >t2->old_field_id)
01002 return 1;
01003 else if ( t1->old_field_id<t2->old_field_id)
01004 return -1;
01005 else
01006 return 0;
01007 }
01008
01009 #ifdef KEY
01010 static void
01011 undo_field_reordering (FLD_ACCESS * flds, int count)
01012 {
01013 for (int i=0; i<count; ++i)
01014 {
01015 flds[i].new_field_id = flds[i].old_field_id;
01016 flds[i].offset = flds[i].old_offset;
01017 }
01018 }
01019 #endif // KEY
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056 void IPO_get_new_ordering()
01057 {
01058 TYPE_LIST::iterator iter;
01059 INDEX i;
01060 FIELD_ID fld_num, sub_fld_num,top_size,k,kk;
01061 CAND_ITEM* p_cand, *sub_cand;
01062 FLD_ACCESS*be_sorted_list,*sub_map;
01063 TOP_FIELD *ref_list;
01064 COUNT count;
01065 TY_SIZE cur_size;
01066 FLD_OFST cur_offset;
01067 INDEX cur_ty_index,cur_struct,size;
01068 PTR_AND_TY_VECTOR::iterator ptr_iter;
01069 BOOL Trace_it=Get_Trace ( TP_IPA,IPA_TRACE_TUNING_NEW ) ;
01070 size=reorder_candidate.size;
01071 for(i=0,p_cand=reorder_candidate.list; i<size; i++,p_cand++)
01072 {
01073 ref_list=p_cand->top_field_info.list;
01074 be_sorted_list=p_cand->fld_info.map;
01075 top_size=p_cand->top_field_info.size;
01076 fld_num=p_cand->fld_info.flatten_fields;
01077
01078 qsort( be_sorted_list,fld_num, sizeof(FLD_ACCESS), Cmp_FLD_ACCESS);
01079
01080 cur_offset=0;
01081 int max_align = 0;
01082 for(k=0;k<fld_num;k++){
01083 be_sorted_list[k].new_field_id=k+1;
01084 cur_size=be_sorted_list[k].offset;
01085 #ifdef KEY
01086 if(!cur_size && k)
01087 {
01088 be_sorted_list[k].offset = be_sorted_list[k-1].offset;
01089 }
01090 else
01091 {
01092 if (be_sorted_list[k].align > max_align)
01093 max_align = be_sorted_list[k].align;
01094 int rem = 0;
01095 if (be_sorted_list[k].align)
01096 rem = cur_offset % be_sorted_list[k].align;
01097 if (rem)
01098 {
01099 be_sorted_list[k].offset = cur_offset +
01100 be_sorted_list[k].align - rem;
01101 cur_offset += (cur_size + be_sorted_list[k].align - rem);
01102 }
01103 else
01104 {
01105 be_sorted_list[k].offset=cur_offset;
01106 cur_offset+=cur_size;
01107 }
01108 }
01109 #else
01110 if(!cur_size && k)
01111 be_sorted_list[k].offset=be_sorted_list[k-1].offset;
01112 else{
01113 be_sorted_list[k].offset=cur_offset;
01114 cur_offset+=cur_size;
01115 }
01116 #endif // KEY
01117 }
01118 #ifdef KEY
01119
01120 {
01121
01122
01123 int rem = 0;
01124 if (max_align && (rem = cur_offset % max_align))
01125 cur_offset += max_align - rem;
01126 }
01127
01128 if (Ty_tab [p_cand->ty_index].size != cur_offset)
01129 undo_field_reordering (be_sorted_list, fld_num);
01130 #endif // KEY
01131
01132 qsort( be_sorted_list,fld_num, sizeof(FLD_ACCESS), Cmp_old_field_id);
01133
01134
01135
01136
01137
01138
01139
01140 if(p_cand->flag.has_enclosed_struct)
01141
01142 for(k=0;k<top_size;k++){
01143 if(cur_ty_index=ref_list[k].ty_idx>>8){
01144 sub_cand=find_in_reorder_candidate(cur_ty_index);
01145 #ifdef KEY
01146 FmtAssert (!sub_cand || sub_cand->fld_info.map,
01147 ("Field reordering information not available"));
01148 if(!sub_cand || !sub_cand->fld_info.map[0].new_field_id){
01149
01150
01151 #else
01152 if(!sub_cand){
01153 #endif // KEY
01154 Handle_ty_map_and_flatten_fields handle_ty(&reorder_local_pool,cur_ty_index);
01155 sub_map=handle_ty.Get_unaltered_map();
01156 sub_fld_num=handle_ty.Get_flatten_fields();
01157 }
01158 else {
01159 sub_map=sub_cand->fld_info.map;
01160 sub_fld_num=sub_cand->fld_info.flatten_fields;
01161 }
01162 mUINT32 sub_fld_start=be_sorted_list[ref_list[k].field_id-1].new_field_id;
01163 mUINT64 sub_off_start=be_sorted_list[ref_list[k].field_id-1].offset;
01164 mUINT32 old_fld_start=be_sorted_list[ref_list[k].field_id-1].old_field_id;
01165 for(kk=0;kk<sub_fld_num;kk++){
01166 be_sorted_list[kk+old_fld_start].new_field_id=
01167 sub_fld_start+sub_map[kk].new_field_id;
01168 be_sorted_list[kk+old_fld_start].offset=
01169 sub_off_start+sub_map[kk].offset;
01170 }
01171
01172 }
01173 }
01174
01175 p_cand->flag.changed=FALSE;
01176 for(k=0;k<fld_num;k++){
01177 if(be_sorted_list[k].new_field_id!=k+1){
01178 p_cand->flag.changed=TRUE;
01179 break;
01180 }
01181 }
01182 if( p_cand->flag.changed){
01183 #ifdef KEY
01184 if (Trace_it)
01185 fprintf (stderr,"CHANGED: Name: %s, size: %lld\n",
01186 &Str_Table[Ty_tab [p_cand->ty_index].name_idx],
01187 Ty_tab[p_cand->ty_index].size);
01188 #endif // KEY
01189 cur_struct=p_cand->ty_index;
01190 Ty_to_cand_map.insert(make_pair(cur_struct,p_cand));
01191
01192 for(ptr_iter=Ptr_and_ty_vector->begin();
01193 ptr_iter!=Ptr_and_ty_vector->end();
01194 ptr_iter++){
01195 if(ptr_iter->pt_index==cur_struct){
01196 Ty_to_cand_map.insert(make_pair(ptr_iter->ty_index,p_cand));
01197 if(Trace_it)
01198 fprintf(TFile,"ADD TO Ptr_and_ty_vector:<%d,%d>\n",
01199 (*ptr_iter).ty_index,(*ptr_iter).pt_index);
01200 }
01201 }
01202 }
01203 }
01204
01205 p_cand=reorder_candidate.list;
01206 if ( Trace_it){
01207 fprintf(TFile,"maping_info:\n");
01208 for( i=0;i<size;p_cand++,i++)
01209 {
01210 TY& ty=Ty_tab[p_cand->ty_index];
01211 fld_num=p_cand->fld_info.flatten_fields;
01212 #ifdef KEY // give some more information
01213
01214 if (!p_cand->flag.changed) continue;
01215 fprintf(TFile,"type name: %s, type id: %d, flatten_fields: %d, changed: %d\n",
01216 Index_To_Str(ty.name_idx),
01217 p_cand->ty_index,
01218 fld_num,
01219 p_cand->flag.changed);
01220 #else
01221 fprintf(TFile,"type name :%s, flatten_fields:%d, changed=%d\n",
01222 Index_To_Str(ty.name_idx),
01223 fld_num,
01224 p_cand->flag.changed);
01225 #endif // KEY
01226 fprintf(TFile,"\nmapping for field_id:\n");
01227 for(UINT j=0;j<fld_num; j++){
01228 fprintf(TFile," %4d",p_cand->fld_info.map[j].new_field_id);
01229 if(j%20==0&& j)
01230 fprintf(TFile,"\n");
01231
01232 }
01233 fprintf(TFile,"\nmapping for offset:\n");
01234 for(UINT j=0;j<fld_num; j++){
01235 #ifdef KEY
01236 fprintf(TFile," %d",p_cand->fld_info.map[j].offset);
01237 #else
01238 fprintf(TFile,"%5d",p_cand->fld_info.map[j].offset);
01239 #endif // KEY
01240 if(j%16==0 && j)
01241 fprintf(TFile,"\n");
01242
01243 }
01244 fprintf(TFile,"\n");
01245 }
01246 }
01247
01248 return;
01249 }
01250
01251 typedef struct{
01252 FIELD_ID new_top_id;
01253 FIELD_ID old_top_id;
01254 }TOP_FLD_ID_TRANS;
01255 INT
01256 Cmp_new_top_id(const void *p1,const void*p2)
01257 {
01258 TOP_FLD_ID_TRANS* t1,*t2;
01259 t1=(TOP_FLD_ID_TRANS*)p1;
01260 t2=(TOP_FLD_ID_TRANS*)p2;
01261 if ( t1->new_top_id >t2->new_top_id)
01262 return 1;
01263 else if ( t1->new_top_id<t2->new_top_id)
01264 return -1;
01265 else
01266 return 0;
01267 }
01268 INT
01269 Cmp_old_top_id(const void *p1,const void*p2)
01270 {
01271 TOP_FLD_ID_TRANS* t1,*t2;
01272 t1=(TOP_FLD_ID_TRANS*)p1;
01273 t2=(TOP_FLD_ID_TRANS*)p2;
01274 if ( t1->old_top_id >t2->old_top_id)
01275 return 1;
01276 else if ( t1->old_top_id<t2->old_top_id)
01277 return -1;
01278 else
01279 return 0;
01280 }
01281
01282
01283
01284
01285
01286
01287
01288
01289 void IPO_reorder_Fld_Tab()
01290 {
01291 MEM_POOL_Popper popper(&reorder_local_pool);
01292
01293 FIELD_ID j,ii;
01294 mUINT32 k;
01295 INDEX i;
01296 FIELD_ID *addr_list,top_size,size;
01297 TOP_FLD_ID_TRANS *trans_list;
01298 CAND_ITEM* p_cand;
01299 FLD *tmp_fld;
01300 FLD_ACCESS *ref_list;
01301 TOP_FIELD *top_list;
01302 tmp_fld= (FLD*)MEM_POOL_Alloc_P(&reorder_local_pool,
01303 sizeof(FLD),TRUE,NULL);
01304 size=reorder_candidate.size;
01305 #ifdef KEY
01306 bool Trace_it=Get_Trace ( TP_IPA,IPA_TRACE_TUNING_NEW );
01307 FLD *tmp_fld1 = (FLD*)MEM_POOL_Alloc_P(&reorder_local_pool,
01308 sizeof(FLD),TRUE,NULL);
01309 #endif // KEY
01310 for(i=0,p_cand=reorder_candidate.list; i<size; i++,p_cand++)
01311 {
01312 #ifdef KEY
01313 bool changed = false;
01314 #endif // KEY
01315 MEM_POOL_Push (&reorder_local_pool);
01316 UINT start_fld_idx=Ty_tab[p_cand->ty_index].u1.fld;
01317 top_size=p_cand->top_field_info.size;
01318 trans_list = (TOP_FLD_ID_TRANS*)MEM_POOL_Alloc_P(&reorder_local_pool,
01319 sizeof(TOP_FLD_ID_TRANS)*top_size,TRUE,NULL);
01320 for(k=0;k<top_size;k++){
01321 mUINT16 old_id=p_cand->top_field_info.list[k].field_id;
01322
01323 trans_list[k].new_top_id=p_cand->fld_info.map[old_id-1].new_field_id-1;
01324 trans_list[k].old_top_id=k;
01325 #ifdef KEY
01326 if (trans_list[k].old_top_id != trans_list[k].new_top_id)
01327 changed = true;
01328 #endif // KEY
01329 }
01330 #ifdef KEY
01331 if (!changed) continue;
01332 #endif // KEY
01333
01334 qsort( trans_list,top_size, sizeof(TOP_FLD_ID_TRANS), Cmp_new_top_id);
01335 for(k=0;k<top_size;k++){
01336 trans_list[k].new_top_id=k;
01337 }
01338 qsort( trans_list,top_size, sizeof(TOP_FLD_ID_TRANS), Cmp_old_top_id);
01339 addr_list = (FIELD_ID*)MEM_POOL_Alloc_P(&reorder_local_pool,
01340 sizeof(FIELD_ID)*top_size,TRUE,NULL);
01341 for(k=0;k<top_size;k++)
01342 addr_list[k]=trans_list[k].new_top_id;
01343
01344
01345 ref_list=p_cand->fld_info.map;
01346 top_list=p_cand->top_field_info.list;
01347
01348 for(ii=0;ii<top_size;ii++){
01349
01350 #ifdef KEY
01351
01352 for (j=0, k=0; (ii==0) && (j<top_size); j++) {
01353
01354
01355 if (addr_list[k] == k) {
01356 k++;
01357 continue;
01358 }
01359 memcpy(tmp_fld,&Fld_Table[addr_list[k]+start_fld_idx],sizeof(FLD));
01360 if (j)
01361 memcpy(&Fld_Table[addr_list[k]+start_fld_idx], tmp_fld1, sizeof(FLD));
01362 else
01363 memcpy(&Fld_Table[addr_list[k]+start_fld_idx], &Fld_Table[k+start_fld_idx],
01364 sizeof(FLD));
01365 k = addr_list[k];
01366 memcpy(tmp_fld1,tmp_fld, sizeof(FLD));
01367 FmtAssert (k != addr_list[k], ("Field reordering error"));
01368 }
01369 #else
01370 if(addr_list[ii]!=ii){
01371 j=ii;
01372 memcpy(tmp_fld,&Fld_Table[ii+start_fld_idx],sizeof(FLD));
01373
01374 while(addr_list[j]!=ii){
01375 k=addr_list[j];
01376 memcpy(&Fld_Table[j+start_fld_idx],
01377 &Fld_Table[k+start_fld_idx],
01378 sizeof(FLD));
01379 addr_list[j]=j;
01380 j=k;
01381 }
01382 memcpy(&Fld_Table[j+start_fld_idx],tmp_fld,sizeof(FLD));
01383 addr_list[j]=j;
01384 }
01385 #endif // KEY
01386
01387
01388 for(k=0;k<top_size;k++)
01389 if(trans_list[k].new_top_id==ii)
01390 break;
01391 FIELD_ID old_top_id=trans_list[k].old_top_id;
01392 FIELD_ID old_field_id=top_list[old_top_id].field_id;
01393 Fld_Table[start_fld_idx+ii].ofst=ref_list[old_field_id-1].offset;
01394 #ifdef KEY
01395 if (Trace_it)
01396 {
01397 #endif // KEY
01398 fprintf(stderr,"<%lld>",Fld_Table[start_fld_idx+ii].ofst);
01399 if((ii+1)%10==0)
01400 fprintf(stderr,"\n");
01401 #ifdef KEY
01402 }
01403 #endif // KEY
01404 if(ii!=top_size-1)
01405
01406 Fld_Table[start_fld_idx+ii].flags &= ~FLD_LAST_FIELD;
01407 else
01408
01409 Fld_Table[start_fld_idx+ii].flags |= FLD_LAST_FIELD;
01410 }
01411 #ifdef KEY
01412 if (Trace_it)
01413 #endif // KEY
01414 fprintf(stderr,"\n");
01415 FLD_OFST pre_ofst;
01416 for(j=0;j<top_size;j++){
01417 k=start_fld_idx+j;
01418
01419
01420 if(j)
01421 FmtAssert(Fld_Table[k].ofst>=pre_ofst,("fld offset must be ascending !\n"));
01422 else
01423 FmtAssert(Fld_Table[k].ofst==0,("first fld offset must be zero !\n"));
01424 pre_ofst=Fld_Table[k].ofst;
01425 }
01426 FmtAssert(Fld_Table[k].flags &FLD_LAST_FIELD,("last fld flag is wrong !\n"));
01427 MEM_POOL_Pop(&reorder_local_pool);
01428 }
01429 return;
01430 }
01431
01432
01433 BOOL map_field_id_and_offset(INDEX index, FIELD_ID old_field_id,WN_OFFSET old_offset,
01434 FIELD_ID &new_field_id, WN_OFFSET &new_offset)
01435 {
01436 CAND_ITEM * cur_cand;
01437 WN_ITER* itr;
01438 UINT i;
01439 FLD_ACCESS *map;
01440 TY_TO_CAND_MAP::const_iterator map_iter;
01441 WN_OFFSET struct_size;
01442 INT64 extra;
01443 char *p_ch=Index_To_Str(Ty_tab[index].name_idx);
01444 TY &this_ty=Ty_tab[index];
01445 map_iter=Ty_to_cand_map.find(index);
01446 if(map_iter==Ty_to_cand_map.end())
01447 return FALSE;
01448 else
01449 cur_cand=map_iter->second;
01450 struct_size=Ty_tab[cur_cand->ty_index].size;
01451
01452
01453
01454
01455 TY_SIZE module=old_offset%struct_size;
01456 if(module==0)
01457 extra=old_offset;
01458 else{
01459 WN_OFFSET tmp=old_offset/struct_size;
01460 extra=tmp*struct_size;
01461 if(old_offset<0)
01462 extra-=struct_size;
01463 }
01464
01465 map=cur_cand->fld_info.map;
01466 new_field_id=map[old_field_id-1].new_field_id;
01467 new_offset=map[old_field_id-1].offset+extra;
01468 return TRUE;
01469
01470 }
01471
01472
01473
01474
01475
01476
01477 void IPO_Modify_WN_for_field_reorder (IPA_NODE* node)
01478 {
01479 WN * wn,*wn1;
01480 CAND_ITEM * cur_cand;
01481 WN_ITER* itr;
01482 FIELD_ID fld_id,new_field_id,i;
01483 FLD_ACCESS *map;
01484 TY_TO_CAND_MAP::const_iterator map_iter;
01485 PTR_AND_TY_VECTOR::iterator ptr_iter;
01486 WN_MAP Parent_Map;
01487 WN_OFFSET old_offset,new_offset;
01488 TY_SIZE struct_size;
01489 WN* parent,*wn_const ;
01490 INDEX point_idx;
01491
01492 Parent_Map=node->Parent_Map();
01493 wn1 = node->Whirl_Tree();
01494 Is_True(wn1 != NULL, (" NULL whirl encountered \n"));
01495 for ( itr = WN_WALK_TreeIter(wn1);
01496 itr != NULL;
01497 itr = WN_WALK_TreeNext(itr)) {
01498
01499 wn = itr->wn;
01500 old_offset=WN_offset(wn);
01501
01502 #ifdef KEY
01503 if (WN_operator(wn) == OPR_LDID)
01504 {
01505 WN * kid;
01506 INDEX addr = WN_ty(wn) >> 8;
01507 if (Ty_tab[addr].kind == KIND_POINTER &&
01508 Ty_Table[TY_pointed (Ty_tab[addr])].kind == KIND_STRUCT)
01509 addr = TY_pointed (Ty_tab[addr]) >> 8;
01510
01511 TY_TO_CAND_MAP::const_iterator map_iter;
01512 if ((Ty_tab[addr].kind == KIND_STRUCT) &&
01513 (map_iter=Ty_to_cand_map.find(addr))!=Ty_to_cand_map.end())
01514 {
01515 WN * tmp = WN_Get_Parent (wn, Parent_Map, Current_Map_Tab);
01516 if (tmp && WN_operator(tmp) == OPR_ADD)
01517 {
01518 for (int i=0; i<WN_kid_count(tmp); ++i)
01519 if ((kid=WN_kid(tmp,i)) && WN_operator(kid) == OPR_INTCONST)
01520 {
01521 CAND_ITEM * cur_cand = map_iter->second;
01522 FLD_ACCESS * fields = cur_cand->fld_info.map;
01523 for (int j=0; j<cur_cand->fld_info.flatten_fields; ++j)
01524 {
01525 if (fields[j].old_offset == WN_const_val (kid))
01526 {
01527 WN_const_val (kid) = fields[j].offset;
01528 break;
01529 }
01530 }
01531 }
01532 }
01533 }
01534 }
01535 #endif // KEY
01536
01537 switch (WN_operator(wn)) {
01538 case OPR_ILOAD:{
01539 OPCODE opcode;
01540 opcode = WN_opcode(wn);
01541 FmtAssert(OPCODE_has_2ty(opcode),("ILoad has two Tys!\n"));
01542 }
01543 case OPR_ISTORE:
01544 case OPR_ILDA:
01545 case OPR_LDA:
01546 case OPR_MSTORE:
01547 case OPR_MLOAD:
01548 case OPR_LDID:
01549 case OPR_STID:{
01550 TY_IDX ty_idx=WN_ty(wn);
01551 INDEX index=ty_idx>>8;
01552 fld_id=WN_field_id(wn);
01553 if(fld_id<=0) continue;
01554 else if (map_field_id_and_offset(index,fld_id,WN_load_offset(wn),
01555 new_field_id,new_offset))
01556 {
01557 WN_set_field_id(wn,new_field_id);
01558 WN_store_offset(wn)=new_offset;
01559 }
01560 break;
01561 }
01562 }
01563 }
01564 #ifdef Is_True
01565 WN_verifier(wn1);
01566 Verify_GLOBAL_SYMTAB();
01567 #endif
01568 node->Set_Whirl_Tree(wn1);
01569 if(Get_Trace ( TP_IPA,IPA_TRACE_TUNING_NEW ))
01570 fdump_tree(TFile, wn1);
01571 return;
01572 }
01573
01574
01575
01576
01577 void Compare_whirl_tree(IPA_NODE* node)
01578 {
01579 WN *wn;
01580 CAND_ITEM * cur_cand;
01581
01582 wn = node->Whirl_Tree();
01583 Is_True(wn != NULL, (" NULL whirl encountered \n"));
01584 if(Get_Trace ( TP_IPA,IPA_TRACE_TUNING_NEW ))
01585 fdump_tree(TFile, wn);
01586 return;
01587 }
01588
01589 void IPO_Finish_reorder()
01590 {
01591 MEM_POOL_Pop(&reorder_local_pool);
01592 }