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 static const char source_file[] = __FILE__;
00037 static const char rcs_id[] = "$Source: /proj/osprey/CVS/open64/osprey1.0/common/targ_info/access/ti_res_res.c,v $ $Revision: 1.1.1.1 $";
00038
00039 #include <alloca.h>
00040 #include <limits.h>
00041
00042 #include "defs.h"
00043 #include "erglob.h"
00044 #include "mempool.h"
00045 #include "bitset.h"
00046 #include "ti_si.h"
00047
00048 #include "ti_res_res.h"
00049
00050
00051
00052
00053 struct ti_res_res {
00054 MEM_POOL *pool;
00055 SI_RRW *rrtab;
00056 INT32 length;
00057 INT32 alloc_size;
00058 BOOL cyclic;
00059
00060
00061
00062
00063 BS *si_ids;
00064
00065 UINT min_rr_length;
00066
00067 SI_RESOURCE_ID_SET *uncommon_res_ids;
00068
00069
00070
00071 SI_BAD_II_SET bad_iis;
00072
00073 };
00074
00075
00076
00077 #define TI_RES_RES_pool(t) ((t)->pool)
00078 #define TI_RES_RES_rrtab(t) ((t)->rrtab)
00079 #define TI_RES_RES_length(t) ((t)->length)
00080 #define TI_RES_RES_alloc_size(t) ((t)->alloc_size)
00081 #define TI_RES_RES_cyclic(t) ((t)->cyclic)
00082 #define TI_RES_RES_si_ids(t) ((t)->si_ids)
00083 #define TI_RES_RES_min_rr_length(t) ((t)->min_rr_length)
00084 #define TI_RES_RES_uncommon_res_ids(t) ((t)->uncommon_res_ids)
00085 #define TI_RES_RES_bad_iis(t) ((t)->bad_iis)
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 static INT32
00102 Cycle_Mod_II(
00103 INT32 cyc,
00104 INT32 ii
00105 )
00106 {
00107 if ( cyc < 0 ) {
00108 do {
00109 cyc += ii;
00110 } while (cyc < 0);
00111 } else if (cyc >= ii) {
00112 do {
00113 cyc -= ii;
00114 } while (cyc >= ii);
00115 }
00116
00117 return cyc;
00118 }
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 void TI_RES_RES_Has_TOP(
00130 TI_RES_RES *res,
00131 TOP opcode
00132 )
00133 {
00134 if ( !BS_MemberP(TI_RES_RES_si_ids(res), TSI_Id(opcode) ) ) {
00135 UINT rr_length;
00136
00137 TI_RES_RES_si_ids(res) = BS_Union1D(TI_RES_RES_si_ids(res),
00138 TSI_Id(opcode),
00139 TI_RES_RES_pool(res));
00140 TI_RES_RES_bad_iis(res) = SI_BAD_II_SET_Union(TI_RES_RES_bad_iis(res),
00141 TSI_Bad_IIs(opcode));
00142
00143 rr_length = SI_RR_Length(TSI_Resource_Requirement(opcode));
00144 if ( rr_length < TI_RES_RES_min_rr_length(res) ) {
00145 TI_RES_RES_min_rr_length(res) = rr_length;
00146 }
00147 }
00148 }
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 static void Check_Reserve_Loop_Control(
00160 TI_RES_RES *res,
00161 TOP opcode,
00162 INT cycle,
00163 SI_RR *rr,
00164 INT *length1,
00165 INT *length2,
00166 INT *cycle_mod_ii
00167 )
00168 {
00169 INT32 rr_length;
00170 INT32 length = TI_RES_RES_length(res);
00171
00172 if ( TI_RES_RES_cyclic(res) ) {
00173 *rr = TSI_II_Resource_Requirement(opcode,length);
00174 }
00175 else {
00176 *rr = TSI_Resource_Requirement(opcode);
00177 }
00178 *cycle_mod_ii = Cycle_Mod_II(cycle,length);
00179
00180 rr_length = SI_RR_Length(*rr);
00181 if ( *cycle_mod_ii + rr_length <= length ) {
00182 *length1 = rr_length;
00183 *length2 = 0;
00184 }
00185 else {
00186 *length1 = length - *cycle_mod_ii;
00187 *length2 = rr_length - *length1;
00188 }
00189 }
00190
00191 #if defined(TARG_SL)
00192 static void Check_Reserve_Loop_Control_For_Alternative_Res(
00193 TI_RES_RES *res,
00194 TOP opcode,
00195 INT cycle,
00196 SI_RR *rr,
00197 INT *length1,
00198 INT *length2,
00199 INT *cycle_mod_ii
00200 )
00201 {
00202 INT32 rr_length;
00203 INT32 length = TI_RES_RES_length(res);
00204
00205 if ( TI_RES_RES_cyclic(res) ) {
00206 *rr = TSI_II_Resource_Requirement(opcode,length);
00207 }
00208 else {
00209 *rr = TSI_Alternative_Resource_Requirement(opcode);
00210 }
00211 *cycle_mod_ii = Cycle_Mod_II(cycle,length);
00212
00213 rr_length = SI_RR_Length(*rr);
00214 if ( *cycle_mod_ii + rr_length <= length ) {
00215 *length1 = rr_length;
00216 *length2 = 0;
00217 }
00218 else {
00219 *length1 = length - *cycle_mod_ii;
00220 *length2 = rr_length - *length1;
00221 }
00222 }
00223
00224 #endif
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 void TI_RES_RES_Set_BB_Cycle_Count(
00236 TI_RES_RES *res,
00237 INT length
00238 )
00239 {
00240 INT i;
00241 BOOL cyclic = TI_RES_RES_cyclic(res);
00242
00243 if ( length > TI_RES_RES_alloc_size(res) ) {
00244 INT new_alloc_size = length * 2;
00245 TI_RES_RES_alloc_size(res) = new_alloc_size;
00246
00247 TI_RES_RES_rrtab(res) = TYPE_MEM_POOL_ALLOC_N(SI_RRW,
00248 TI_RES_RES_pool(res),
00249 new_alloc_size);
00250 if ( cyclic ) {
00251 TI_RES_RES_uncommon_res_ids(res)
00252 = TYPE_MEM_POOL_ALLOC_N(SI_RESOURCE_ID_SET,
00253 TI_RES_RES_pool(res),
00254 new_alloc_size);
00255 }
00256 }
00257
00258 TI_RES_RES_length(res) = length;
00259
00260
00261
00262 for ( i = 0; i < length; ++i ) {
00263 TI_RES_RES_rrtab(res)[i] = SI_RRW_Initial();
00264 }
00265
00266 if ( cyclic ) {
00267 INT id;
00268 BS *si_ids = TI_RES_RES_si_ids(res);
00269 SI_RESOURCE_ID_SET *uncommon_res_ids = TI_RES_RES_uncommon_res_ids(res);
00270 INT common_length = MIN(TI_RES_RES_min_rr_length(res), length);
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 for ( i = 0; i < length; ++i ) {
00286 uncommon_res_ids[i] = SI_RESOURCE_ID_SET_Universe();
00287 }
00288
00289 for ( id = BS_Choose(si_ids); id != BS_CHOOSE_FAILURE;
00290 id = BS_Choose_Next(si_ids,id)
00291 ) {
00292 const SI_RESOURCE_ID_SET* resource_ids_used
00293 = SI_ID_II_Cycle_Resource_Ids_Used(id,length);
00294
00295 for ( i = 0; i < common_length; ++i ) {
00296 uncommon_res_ids[i]
00297 = SI_RESOURCE_ID_SET_Intersection(uncommon_res_ids[i],
00298 resource_ids_used[i]);
00299 }
00300 }
00301
00302
00303
00304 for ( i = 0; i < common_length; ++i ) {
00305 uncommon_res_ids[i] =
00306 SI_RESOURCE_ID_SET_Complement(uncommon_res_ids[i]);
00307 }
00308 }
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 TI_RES_RES *TI_RES_RES_Alloc(
00321 BOOL cyclic,
00322 MEM_POOL *pool
00323 )
00324 {
00325 TI_RES_RES *res = TYPE_MEM_POOL_ALLOC(TI_RES_RES, pool);
00326
00327 TI_RES_RES_pool(res) = pool;
00328 TI_RES_RES_cyclic(res) = cyclic;
00329 TI_RES_RES_bad_iis(res) = SI_BAD_II_SET_Empty();
00330 TI_RES_RES_length(res) = 0;
00331 TI_RES_RES_alloc_size(res) = 0;
00332 TI_RES_RES_min_rr_length(res) = UINT_MAX;
00333
00334 if ( cyclic ) {
00335 TI_RES_RES_si_ids(res) = BS_Create_Empty(SI_ID_Count(), pool);
00336 }
00337
00338 return res;
00339 }
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 BOOL TI_RES_RES_Resources_Available(
00351 TI_RES_RES *res,
00352 TOP opcode,
00353 INT cycle
00354 )
00355 {
00356 INT cycle_mod_ii;
00357 INT length1;
00358 INT length2;
00359 INT i;
00360 SI_RR rr;
00361 SI_RRW *rrtab = TI_RES_RES_rrtab(res);
00362
00363 Check_Reserve_Loop_Control(res,opcode,cycle,
00364 &rr,&length1,&length2,&cycle_mod_ii);
00365
00366 for ( i = 0; i < length1; ++i ) {
00367 SI_RRW reserved = SI_RRW_Reserve(rrtab[cycle_mod_ii+i],
00368 SI_RR_Cycle_RRW(rr,i));
00369 if ( SI_RRW_Has_Overuse(reserved) ) return FALSE;
00370 }
00371
00372 for ( i = 0; i < length2; ++i ) {
00373 SI_RRW reserved = SI_RRW_Reserve(rrtab[i],SI_RR_Cycle_RRW(rr,i+length1));
00374 if ( SI_RRW_Has_Overuse(reserved) ) return FALSE;
00375 }
00376
00377 return TRUE;
00378 }
00379
00380 #if defined(TARG_SL)
00381 BOOL TI_RES_RES_Alternative_Resources_Available(
00382 TI_RES_RES *res,
00383 TOP opcode,
00384 INT cycle
00385 )
00386 {
00387 INT cycle_mod_ii;
00388 INT length1;
00389 INT length2;
00390 INT i;
00391 SI_RR rr;
00392 SI_RRW *rrtab = TI_RES_RES_rrtab(res);
00393
00394 Check_Reserve_Loop_Control_For_Alternative_Res(res,opcode,cycle,
00395 &rr,&length1,&length2,&cycle_mod_ii);
00396
00397 for ( i = 0; i < length1; ++i ) {
00398 SI_RRW reserved = SI_RRW_Reserve(rrtab[cycle_mod_ii+i],
00399 SI_RR_Cycle_RRW(rr,i));
00400 if ( SI_RRW_Has_Overuse(reserved) ) return FALSE;
00401 }
00402
00403 for ( i = 0; i < length2; ++i ) {
00404 SI_RRW reserved = SI_RRW_Reserve(rrtab[i],SI_RR_Cycle_RRW(rr,i+length1));
00405 if ( SI_RRW_Has_Overuse(reserved) ) return FALSE;
00406 }
00407
00408 return TRUE;
00409 }
00410
00411 #endif
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422 void TI_RES_RES_Reserve_Resources(
00423 TI_RES_RES *res,
00424 TOP opcode,
00425 INT cycle
00426 )
00427 {
00428 INT cycle_mod_ii;
00429 INT length1;
00430 INT length2;
00431 INT i;
00432 SI_RR rr;
00433 SI_RRW *rrtab = TI_RES_RES_rrtab(res);
00434
00435 Check_Reserve_Loop_Control(res,opcode,cycle,
00436 &rr,&length1,&length2,&cycle_mod_ii);
00437
00438 for ( i = 0; i < length1; ++i ) {
00439 rrtab[cycle_mod_ii+i]
00440 = SI_RRW_Reserve(rrtab[cycle_mod_ii+i],SI_RR_Cycle_RRW(rr,i));
00441 }
00442
00443 for ( i = 0; i < length2; ++i ) {
00444 rrtab[i] = SI_RRW_Reserve(rrtab[i],SI_RR_Cycle_RRW(rr,i+length1));
00445 }
00446 }
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457 void TI_RES_RES_Unreserve_Resources(
00458 TI_RES_RES *res,
00459 TOP opcode,
00460 INT cycle
00461 )
00462 {
00463 INT cycle_mod_ii;
00464 INT length1;
00465 INT length2;
00466 INT i;
00467 SI_RR rr;
00468 SI_RRW *rrtab = TI_RES_RES_rrtab(res);
00469
00470 Check_Reserve_Loop_Control(res,opcode,cycle,
00471 &rr,&length1,&length2,&cycle_mod_ii);
00472
00473 for ( i = 0; i < length1; ++i ) {
00474 rrtab[cycle_mod_ii+i]
00475 = SI_RRW_Unreserve(rrtab[cycle_mod_ii+i],SI_RR_Cycle_RRW(rr,i));
00476 }
00477
00478 for ( i = 0; i < length2; ++i ) {
00479 rrtab[i] = SI_RRW_Unreserve(rrtab[i],SI_RR_Cycle_RRW(rr,i+length1));
00480 }
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 BOOL TI_RES_RES_Is_Bad_II(
00493 TI_RES_RES *res,
00494 INT ii
00495 )
00496 {
00497 return SI_BAD_II_SET_MemberP(TI_RES_RES_bad_iis(res),ii);
00498 }
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509 BOOL TI_RES_RES_Resources_Relevant(
00510 TI_RES_RES *res,
00511 TOP opcode1,
00512 TOP opcode2,
00513 INT offset
00514 )
00515 {
00516 INT length1, length2, i;
00517 const INT32 length = TI_RES_RES_length(res);
00518 const SI_RESOURCE_ID_SET *const res_ids1
00519 = TSI_II_Cycle_Resource_Ids_Used(opcode1,length);
00520 const SI_RESOURCE_ID_SET *const res_ids2
00521 = TSI_II_Cycle_Resource_Ids_Used(opcode2,length);
00522 const INT rr1_length
00523 = SI_RR_Length(TSI_II_Resource_Requirement(opcode1,length));
00524 const INT rr2_length
00525 = SI_RR_Length(TSI_II_Resource_Requirement(opcode2,length));
00526 const INT offset_mod_ii = Cycle_Mod_II(offset,length);
00527 const SI_RESOURCE_ID_SET *const uncommon_res_ids
00528 = TI_RES_RES_uncommon_res_ids(res);
00529
00530 FmtAssert (TI_RES_RES_cyclic(res),
00531 ("TI_RES_RES_Resources_Relevant not applicable to non-cyclic schedules"));
00532
00533
00534
00535
00536 length1 = rr1_length - offset_mod_ii;
00537 if ( rr2_length < length1 ) length1 = rr2_length;
00538
00539 for ( i = 0; i < length1; ++i ) {
00540 if ( SI_RESOURCE_ID_SET_Intersection4_Non_Empty(
00541 res_ids1[i + offset_mod_ii],
00542 uncommon_res_ids[i + offset_mod_ii],
00543 res_ids2[i],
00544 uncommon_res_ids[i] )
00545 ) {
00546 return TRUE;
00547 }
00548 }
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559 length2 = (rr2_length + offset_mod_ii) - length;
00560 if ( length > 0 ) {
00561 if ( rr1_length < length2 ) length2 = rr1_length;
00562
00563 for ( i = 0; i < length2; ++i ) {
00564 if ( SI_RESOURCE_ID_SET_Intersection4_Non_Empty(
00565 res_ids1[i],
00566 uncommon_res_ids[i],
00567 res_ids2[i + length - offset_mod_ii],
00568 uncommon_res_ids[i + length - offset_mod_ii] )
00569 ) {
00570 return TRUE;
00571 }
00572 }
00573 }
00574
00575 return FALSE;
00576 }
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587 BOOL TI_RES_RES_Resources_Equivalent(
00588 TI_RES_RES *res,
00589 TOP opcode1,
00590 TOP opcode2
00591 )
00592 {
00593 INT i;
00594 const INT32 length = TI_RES_RES_length(res);
00595 SI_RR rr1 = TSI_II_Resource_Requirement(opcode1,length);
00596 SI_RR rr2 = TSI_II_Resource_Requirement(opcode2,length);
00597
00598 if ( rr1 == rr2 ) return TRUE;
00599
00600 if ( SI_RR_Length(rr1) != SI_RR_Length(rr2) ) return FALSE;
00601
00602 for (i = 0; i < SI_RR_Length(rr1); ++i) {
00603 if ( SI_RR_Cycle_RRW(rr1,i) != SI_RR_Cycle_RRW(rr2,i) )
00604 return FALSE;
00605 }
00606
00607 return TRUE;
00608 }
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619 BOOL TI_RES_RES_Resources_Grainy(
00620 TI_RES_RES *res,
00621 TOP opcode
00622 )
00623 {
00624 INT i;
00625 const INT32 length = TI_RES_RES_length(res);
00626 SI_RESOURCE_ID_SET *uncommon_res_ids = TI_RES_RES_uncommon_res_ids(res);
00627 UINT min_rr_length = TI_RES_RES_min_rr_length(res);
00628 const SI_RESOURCE_ID_SET* res_used
00629 = TSI_II_Cycle_Resource_Ids_Used(opcode,length);
00630 INT res_used_length
00631 = SI_RR_Length(TSI_II_Resource_Requirement(opcode,length));
00632
00633 if ( min_rr_length < res_used_length ) return TRUE;
00634
00635 for ( i = 0; i < min_rr_length; ++i ) {
00636 if ( SI_RESOURCE_ID_SET_Intersection_Non_Empty(res_used[i],
00637 uncommon_res_ids[i])
00638 ) {
00639 return TRUE;
00640 }
00641 }
00642
00643 return FALSE;
00644 }
00645
00646
00647 INT TI_RES_RES_Resources_Length(
00648 TI_RES_RES *res,
00649 TOP opcode
00650 )
00651 {
00652 return SI_RR_Length(TSI_Resource_Requirement(opcode));
00653 }
00654
00655
00656 void TI_RES_RES_Print(FILE *fp, TI_RES_RES *res)
00657 {
00658 INT i;
00659 for (i = 0; i < TI_RES_RES_length(res); i++)
00660 fprintf(fp, "%d --> 0x%0llx\n", i, TI_RES_RES_rrtab(res)[i]);
00661 }
00662
00663
00664 BOOL TI_RES_RES_Equal(TI_RES_RES *res1, TI_RES_RES *res2)
00665 {
00666 INT i;
00667 if (TI_RES_RES_length(res1) != TI_RES_RES_length(res2)) return FALSE;
00668 for (i = 0; i < TI_RES_RES_length(res1); i++)
00669 if (TI_RES_RES_rrtab(res1)[i] != TI_RES_RES_rrtab(res2)[i])
00670 return FALSE;
00671 return TRUE;
00672 }
00673