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