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
00038
00039
00040
00041
00042
00044
00045
00046
00047
00048
00049
00050
00051 #include "defs.h"
00052 #include "cg.h"
00053 #include "register.h"
00054 #include "gra_bb.h"
00055 #include "gra_lrange.h"
00056 #include "gra_para_region.h"
00057 #include "bb.h"
00058 #include "tn.h"
00059 #include "gra_grant.h"
00060
00061
00062 GRA_PARA_REGION_MGR gra_para_region_mgr;
00063
00065
00066 void
00067 GRA_PARA_REGION::Add_BB( BB* bb )
00068 {
00069 BBlist_Add_BB(&internal_bbs, bb);
00070 return;
00071 }
00072
00074
00075 void
00076 GRA_PARA_REGION_MGR::Initialize(void)
00077 {
00078 MEM_POOL_Push(&MEM_local_pool);
00079
00080 _map = TYPE_MEM_POOL_ALLOC_N(GRA_PARA_REGION*, &MEM_local_pool, Last_Region_Id() + 1);
00081
00082 bzero(_map, sizeof(GRA_PARA_REGION*) * (Last_Region_Id() + 1));
00083
00084 _rid_pair_map = TYPE_MEM_POOL_ALLOC_N(RID*, &MEM_local_pool, Last_Region_Id() + 1);
00085
00086 bzero(_rid_pair_map, sizeof(RID*) * (Last_Region_Id() + 1));
00087
00088 _alloc_count = 0;
00089
00090 minor_rids = VECTOR_Init( Last_Region_Id()+1, &MEM_local_pool);
00091
00092 return;
00093 }
00094
00096
00097 GRA_PARA_REGION*
00098 GRA_PARA_REGION_MGR::Create( RID* rid)
00099 {
00100 ISA_REGISTER_CLASS rc;
00101
00102 GRA_PARA_REGION* region = TYPE_MEM_POOL_ALLOC(GRA_PARA_REGION, &MEM_local_pool);
00103
00104 _alloc_count++;
00105
00106 region->rid = rid;
00107
00108 FOR_ALL_ISA_REGISTER_CLASS( rc ) {
00109
00110 region->registers_use[rc] = REGISTER_SET_EMPTY_SET;
00111
00112 region->registers_def[rc] = REGISTER_SET_EMPTY_SET;
00113 }
00114
00115 region->flags = (PARA_REGION_FLAG) 0;
00116
00117 return region;
00118 }
00119
00121 GRA_PARA_REGION*
00122 GRA_PARA_REGION_MGR::Create_Region( RID* rid )
00123 {
00124 GRA_PARA_REGION* region = Create(rid);
00125
00126 region->next = _first_para_region;
00127
00128 _first_para_region = region;
00129
00130 Is_True((RID_TYPE_minor(rid) || RID_TYPE_major(rid)) ,
00131 ("unsupport region type when creating parallel region"));
00132
00133 if(RID_TYPE_minor(rid)) {
00134 region->Set_Region_Minor();
00135 }
00136 else if (RID_TYPE_major(rid)) {
00137 region->Set_Region_Major();
00138 }
00139
00140 return region;
00141 }
00142
00144
00145
00146
00147
00148
00149 GRA_PARA_REGION*
00150 GRA_PARA_REGION_MGR::Get( RID* rid )
00151 {
00152 if ( rid != NULL) {
00153 Is_True(RID_id(rid) <= Last_Region_Id(), ("Region out of bounds"));
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 if(!RID_TYPE_sl2_para(rid))
00165
00166 return NULL;
00167
00168 if ( _map[RID_id(rid)] != NULL )
00169 return _map[RID_id(rid)];
00170 else
00171 return _map[RID_id(rid)] = Create_Region(rid);
00172 }
00173 return NULL;
00174 }
00175
00176
00177
00178 void
00179 GRA_PARA_REGION_MGR::Build_Map_For_Pair_Region(void)
00180 {
00181 BB* bb;
00182 for(bb = REGION_First_BB; bb != NULL; bb=BB_next(bb))
00183 {
00184 if(BB_rid(bb) && RID_parent(BB_rid(bb)) && RID_TYPE_minor(BB_rid(bb)))
00185 {
00186 RID* parent = RID_parent(BB_rid(bb));
00187
00188
00189
00190
00191
00192 RID* kid0 = RID_first_kid(parent);
00193 RID* kid1 = RID_next(kid0);
00194 _rid_pair_map[RID_id(kid0)] = kid1;
00195 _rid_pair_map[RID_id(kid1)] = kid0;
00196 }
00197 }
00198 return;
00199 }
00200
00201
00202
00203
00204
00205 void
00206 GRA_PARA_REGION_MGR::Collect_Share_Registers_For_Pair_Regions(GRA_PARA_REGION* r1, GRA_PARA_REGION* r2)
00207 {
00208 BBLIST* list1, *list2, *item;
00209 BB* bb;
00210
00211 list1 = r1->Internal_BBs();
00212
00213 list2 = r2->Internal_BBs();
00214
00215 REGISTER_SET unused_set1 = REGISTER_CLASS_allocatable(ISA_REGISTER_CLASS_integer);
00216
00217 REGISTER_SET unused_set2 = REGISTER_CLASS_allocatable(ISA_REGISTER_CLASS_integer);
00218
00219 FOR_ALL_BBLIST_ITEMS(list1, item)
00220 {
00221 bb = BBLIST_item(item);
00222 unused_set1 = REGISTER_SET_Intersection(unused_set1, GRA_Local_Register_Grant(bb, ISA_REGISTER_CLASS_integer));
00223 }
00224
00225 FOR_ALL_BBLIST_ITEMS(list2, item)
00226 {
00227 bb = BBLIST_item(item);
00228
00229 unused_set2 = REGISTER_SET_Intersection(unused_set2, GRA_Local_Register_Grant(bb, ISA_REGISTER_CLASS_integer));
00230 }
00231
00232 REGISTER_SET unused_share_set = REGISTER_SET_Intersection(unused_set1, unused_set2);
00233
00234 Set_Unused_Share(unused_share_set);
00235
00236 vector < REGISTER > share_register_index;
00237 for(INT i=0; i < REGISTER_MAX+1; i++)
00238 {
00239 if(unused_share_set & (1<< i))
00240 share_register_index.push_back(i);
00241 }
00242
00243 INT size = share_register_index.size();
00244
00245 if(size)
00246 {
00247 #define thread_num 2
00248
00249 INT count = size / thread_num ;
00250
00251 for(INT i = 0; i < count; i++) {
00252
00253 REGISTER reg = share_register_index.back();
00254
00255 share_register_index.pop_back();
00256
00257 r1->Add_Reg_To_LRA_Budget(reg);
00258 }
00259
00260 for(INT i = 0; i < size-count; i++) {
00261
00262 REGISTER reg = share_register_index.back();
00263
00264 share_register_index.pop_back();
00265
00266 r2->Add_Reg_To_LRA_Budget(reg);
00267 }
00268 }
00269 return;
00270 }
00271
00272
00273
00274 void
00275 GRA_PARA_REGION_MGR::Grant_Register_For_Region(GRA_PARA_REGION* region)
00276 {
00277 BB* bb;
00278 BBLIST * item;
00279
00280 BBLIST * bblist = region->Internal_BBs();
00281
00282 FOR_ALL_BBLIST_ITEMS(bblist, item)
00283 {
00284 bb = BBLIST_item(item);
00285
00286 REGISTER_SET reg_set = GRA_Local_Register_Grant(bb, ISA_REGISTER_CLASS_integer);
00287
00288 reg_set = REGISTER_SET_Difference(reg_set, share_unused);
00289
00290 reg_set = REGISTER_SET_Union(reg_set, region->Get_LRA_Reg_Budget());
00291
00292 GRA_GRANT_REGISTER_SET_Set_For_BB(bb, ISA_REGISTER_CLASS_integer, reg_set);
00293 }
00294 return;
00295 }
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 void
00309 GRA_PARA_REGION_MGR::Set_Region_LRA_Budget()
00310 {
00311
00312 vector < RID* > rid_processed;
00313
00314 for(int i = 0; i < VECTOR_count(minor_rids); i++)
00315 {
00316
00317 RID* rid = (RID*)VECTOR_element(minor_rids, i);
00318
00319 Is_True((rid), ("RID is null for minor thread in register allocation check"));
00320
00321 RID* pair_rid = _rid_pair_map[RID_id(rid)];
00322
00323 Is_True((pair_rid), ("PAIR RID is null for minor thread in register allocation check"));
00324
00325 if(find(rid_processed.begin(), rid_processed.end(), rid) != rid_processed.end())
00326 continue;
00327
00328 GRA_PARA_REGION * region = _map[RID_id(rid)];
00329
00330 Is_True((region), ("has no region for this rid"));
00331
00332 GRA_PARA_REGION * pair_region = _map[RID_id(pair_rid)];
00333
00334 Collect_Share_Registers_For_Pair_Regions(region, pair_region);
00335
00336 Grant_Register_For_Region(region);
00337
00338 Grant_Register_For_Region(pair_region);
00339
00340 rid_processed.push_back(rid);
00341
00342 rid_processed.push_back(pair_rid);
00343 }
00344 return;
00345 }
00346
00347
00348
00349 void
00350 GRA_PARA_REGION_MGR::Add_Rid_Into_Minor_Vector(RID * rid)
00351 {
00352 if(!VECTOR_Member_Element(minor_rids, rid))
00353 VECTOR_Add_Element(minor_rids, rid);
00354 return;
00355 }
00356
00357
00358 GRA_PARA_REGION *
00359 GRA_PARA_REGION_MGR::Get_Pair_Region(GRA_PARA_REGION* region)
00360 {
00361
00362 RID* rid = region->Rid();
00363
00364 RID* pair_rid = Get_Pair_Rid(rid);
00365
00366 return Get(pair_rid);
00367 }
00368
00369 void
00370 GRA_PARA_REGION_MGR::Pre_Reserve_Registers_For_Minor()
00371 {
00372
00373 vector < RID* > rid_processed;
00374
00375 for(int i = 0; i < VECTOR_count(minor_rids); i++)
00376 {
00377
00378 RID* rid = (RID*)VECTOR_element(minor_rids, i);
00379
00380 Is_True((rid), ("RID is null for minor thread in register allocation check"));
00381
00382 RID* pair_rid = _rid_pair_map[RID_id(rid)];
00383
00384 Is_True((rid), ("PAIR RID is null for minor thread in register allocation check"));
00385
00386 if(find(rid_processed.begin(), rid_processed.end(), rid) != rid_processed.end())
00387 continue;
00388
00389 GRA_PARA_REGION * region = _map[RID_id(rid)];
00390
00391 Is_True((region), ("has no region for this rid"));
00392
00393 GRA_PARA_REGION * pair_region = _map[RID_id(pair_rid)];
00394
00395 Is_True((pair_region), ("NULL pair region for current rid"));
00396
00397 ISA_REGISTER_CLASS rc = ISA_REGISTER_CLASS_integer;
00398
00399 #define ODD_RESERVE_REGS 0xaaaaaaaa
00400 #define EVEN_RESERVE_REGS 0x55555554
00401
00402 region->Set_Registers_Exclude(rc, (REGISTER_SET)EVEN_RESERVE_REGS);
00403
00404 pair_region->Set_Registers_Exclude(rc, (REGISTER_SET)ODD_RESERVE_REGS);
00405
00406 rid_processed.push_back(rid);
00407
00408 rid_processed.push_back(pair_rid);
00409 }
00410 return;
00411 }
00412
00413
00414
00415
00416 void
00417 GRA_PARA_REGION::Collect_Reg_Used_And_Def_For_BBs(void)
00418 {
00419 BB* bb;
00420 OP* op;
00421 BBLIST * item;
00422
00423 BBLIST * bblist = Internal_BBs();
00424
00425 GRA_PARA_REGION * pair_region = gra_para_region_mgr.Get_Pair_Region(this);
00426 FOR_ALL_BBLIST_ITEMS(bblist, item)
00427 {
00428 bb = BBLIST_item(item);
00429
00430 FOR_ALL_BB_OPs(bb, op)
00431 {
00432
00433 for(int i =0; i < OP_opnds(op); i++)
00434 {
00435
00436 TN* tn = OP_opnd(op, i);
00437
00438 if(TN_is_register(tn) && !TN_is_zero_reg(tn)) {
00439
00440 Make_Register_Used(TN_register_class(tn), TN_register(tn));
00441
00442 if(TN_register_class(tn) == ISA_REGISTER_CLASS_integer)
00443 {
00444
00445 REGISTER_SET def_set = pair_region ->Registers_Defined(TN_register_class(tn));
00446
00447 if(REGISTER_SET_Intersection1(def_set, TN_register(tn)))
00448 Fail_FmtAssertion(("TN %d has same register conflict in BB %d\n"), TN_number(tn), BB_id(bb));
00449 }
00450 }
00451 }
00452
00453 for(int i =0; i < OP_results(op); i++)
00454 {
00455 TN* tn = OP_result(op, i);
00456
00457 if(TN_is_register(tn) ) {
00458
00459 Make_Register_Defined(TN_register_class(tn), TN_register(tn));
00460
00461 if(TN_register_class(tn) == ISA_REGISTER_CLASS_integer) {
00462
00463 REGISTER_SET use_set = pair_region ->Registers_Used(TN_register_class(tn));
00464
00465 REGISTER_SET def_set = pair_region ->Registers_Defined(TN_register_class(tn));
00466
00467 if(REGISTER_SET_Intersection1(def_set, TN_register(tn)) ||
00468 REGISTER_SET_Intersection1(use_set, TN_register(tn)))
00469 Fail_FmtAssertion(("TN %d has same register conflict in BB %d\n"), TN_number(tn), BB_id(bb));
00470
00471 }
00472 }
00473 }
00474 }
00475 }
00476 return;
00477 }
00478 void
00479 GRA_PARA_REGION_MGR::Check_Register_Allocation(void)
00480 {
00481
00482 if(!minor_rids ) return;
00483
00484 for(int i = 0; i < VECTOR_count(minor_rids); i++)
00485 {
00486 RID* rid = (RID*)VECTOR_element(minor_rids, i);
00487
00488 Is_True((rid), ("RID is null for minor thread in register allocation check"));
00489
00490 RID* pair_rid = _rid_pair_map[RID_id(rid)];
00491
00492 Is_True((pair_rid), ("PAIR_RID is null for minor thread in register allocation check"));
00493
00494 GRA_PARA_REGION * region = _map[RID_id(rid)];
00495
00496 Is_True((region), ("has no region for this rid"));
00497
00498 GRA_PARA_REGION * pair_region = _map[RID_id(pair_rid)];
00499
00500 region->Collect_Reg_Used_And_Def_For_BBs();
00501
00502 pair_region->Collect_Reg_Used_And_Def_For_BBs();
00503
00504 ISA_REGISTER_CLASS rc;
00505
00506 FOR_ALL_ISA_REGISTER_CLASS(rc)
00507 {
00508 if(rc == ISA_REGISTER_CLASS_integer) {
00509
00510 REGISTER_SET use_set1 = region->Registers_Used(rc);
00511
00512 REGISTER_SET use_set2 = pair_region->Registers_Used(rc);
00513
00514 REGISTER_SET def_set1 = region->Registers_Defined(rc);
00515
00516 REGISTER_SET def_set2 = pair_region->Registers_Defined(rc);
00517
00518 if(REGISTER_SET_Intersection(use_set1, def_set2) ||
00519 REGISTER_SET_Intersection(use_set2, def_set1) ||
00520 REGISTER_SET_Intersection(def_set1, def_set2) )
00521 Fail_FmtAssertion("register allocation conflict for minor thread" );
00522 }
00523 }
00524
00525 VECTOR_Delete_Element(minor_rids, rid);
00526 VECTOR_Delete_Element(minor_rids, pair_rid);
00527
00528 }
00529 return;
00530 }
00531