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 static const char source_file[] = __FILE__;
00038
00039 #include <stdio.h>
00040 #include <math.h>
00041
00042 #include "defs.h"
00043 #include "erglob.h"
00044 #include "mempool.h"
00045 #include "topcode.h"
00046 #include "ti_si.h"
00047
00048 #include "ti_res_count.h"
00049
00050
00051
00052 struct ti_res_count {
00053 INT32 bad_ii[SI_BAD_II_SET_MAX+1];
00054 double *vec;
00055 };
00056
00057
00058
00059 #define TI_RES_COUNT_bad_ii(r,i) ((r)->bad_ii[(i)])
00060 #define TI_RES_COUNT_vec(r,i) ((r)->vec[(i)])
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 TI_RES_COUNT *
00072 TI_RES_COUNT_Alloc(
00073 MEM_POOL *pool
00074 )
00075 {
00076 TI_RES_COUNT *counts = TYPE_MEM_POOL_ALLOC(TI_RES_COUNT, pool);
00077 counts->vec = TYPE_MEM_POOL_ALLOC_N(double, pool, SI_resource_count);
00078 if ( !MEM_POOL_Zeroed(pool) ) {
00079 bzero(counts->vec, sizeof(double) * SI_resource_count);
00080 bzero(counts->bad_ii, sizeof(counts->bad_ii));
00081 }
00082 return counts;
00083 }
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 double
00095 TI_RES_COUNT_Min_Cycles(
00096 TI_RES_COUNT *res_counts
00097 )
00098 {
00099 INT32 i;
00100 double min_cycles = -1.0;
00101
00102 for ( i = 0; i < SI_resource_count; ++i ) {
00103 double this_min = TI_RES_COUNT_vec(res_counts,i)
00104 / SI_RESOURCE_ID_Avail_Per_Cycle(i);
00105
00106 if ( this_min > min_cycles ) min_cycles = this_min;
00107 }
00108 return min_cycles;
00109 }
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 INT32
00121 TI_RES_COUNT_Min_II(
00122 TI_RES_COUNT *res_counts
00123 )
00124 {
00125 INT32 min_ii;
00126
00127 for ( min_ii = ceil(TI_RES_COUNT_Min_Cycles(res_counts));
00128 min_ii <= SI_BAD_II_SET_MAX;
00129 ++min_ii
00130 ) {
00131 INT ops_with_bad_ii = TI_RES_COUNT_bad_ii(res_counts,min_ii);
00132
00133 Is_True(ops_with_bad_ii >= 0, ("negative count of OPs with bad II"));
00134 if ( ops_with_bad_ii == 0 ) break;
00135 }
00136
00137 return min_ii;
00138 }
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 void
00150 TI_RES_COUNT_Add_Op_Resources(
00151 TI_RES_COUNT *res_counts,
00152 TOP opcode
00153 )
00154 {
00155 INT i;
00156 TOP topcode = opcode;
00157 SI_BAD_II_SET bad_iis = TSI_Bad_IIs(topcode);
00158 SI_RESOURCE_TOTAL* rt_vec = TSI_Resource_Total_Vector(topcode);
00159
00160 for ( i = 0; i < TSI_Resource_Total_Vector_Size(topcode); ++i ) {
00161 SI_RESOURCE_ID id = SI_RESOURCE_TOTAL_Resource_Id(rt_vec+i);
00162 UINT count = SI_RESOURCE_TOTAL_Total_Used(rt_vec+i);
00163
00164 TI_RES_COUNT_vec(res_counts,id) += count;
00165 }
00166
00167 for ( i = SI_RR_Length(TSI_Resource_Requirement(topcode));
00168 i > 0;
00169 --i
00170 ) {
00171 if ( SI_BAD_II_SET_MemberP(bad_iis, i) ) {
00172 ++TI_RES_COUNT_bad_ii(res_counts, i);
00173 }
00174 }
00175 }
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 void
00187 TI_RES_COUNT_Add_Op_Resources_Scaled(
00188 TI_RES_COUNT *res_counts,
00189 TOP opcode,
00190 double factor
00191 )
00192 {
00193 INT i;
00194 TOP topcode = opcode;
00195 SI_BAD_II_SET bad_iis = TSI_Bad_IIs(topcode);
00196 SI_RESOURCE_TOTAL *rt_vec = TSI_Resource_Total_Vector(topcode);
00197
00198 for ( i = 0; i < TSI_Resource_Total_Vector_Size(topcode); ++i ) {
00199 SI_RESOURCE_ID id = SI_RESOURCE_TOTAL_Resource_Id(rt_vec+i);
00200 UINT count = SI_RESOURCE_TOTAL_Total_Used(rt_vec+i);
00201
00202 TI_RES_COUNT_vec(res_counts,id) += count * factor;
00203 }
00204
00205 for ( i = SI_RR_Length(TSI_Resource_Requirement(topcode));
00206 i > 0;
00207 --i
00208 ) {
00209 if ( SI_BAD_II_SET_MemberP(bad_iis, i) ) {
00210 ++TI_RES_COUNT_bad_ii(res_counts, i);
00211 }
00212 }
00213 }
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 void
00225 TI_RES_COUNT_Subtract_Op_Resources(
00226 TI_RES_COUNT *res_counts,
00227 TOP opcode
00228 )
00229 {
00230 INT i;
00231 TOP topcode = opcode;
00232 SI_BAD_II_SET bad_iis = TSI_Bad_IIs(topcode);
00233 SI_RESOURCE_TOTAL *rt_vec = TSI_Resource_Total_Vector(topcode);
00234
00235 for ( i = 0; i < TSI_Resource_Total_Vector_Size(topcode); ++i ) {
00236 SI_RESOURCE_ID id = SI_RESOURCE_TOTAL_Resource_Id(rt_vec+i);
00237 UINT count = SI_RESOURCE_TOTAL_Total_Used(rt_vec+i);
00238
00239 TI_RES_COUNT_vec(res_counts,id) -= count;
00240 }
00241
00242 for ( i = SI_RR_Length(TSI_Resource_Requirement(topcode));
00243 i > 0;
00244 --i
00245 ) {
00246 if ( SI_BAD_II_SET_MemberP(bad_iis, i) ) {
00247 --TI_RES_COUNT_bad_ii(res_counts, i);
00248 }
00249 }
00250 }
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 void
00262 TI_RES_COUNT_Subtract_Op_Resources_Scaled(
00263 TI_RES_COUNT *res_counts,
00264 TOP opcode,
00265 double factor
00266 )
00267 {
00268 INT i;
00269 TOP topcode = opcode;
00270 SI_BAD_II_SET bad_iis = TSI_Bad_IIs(topcode);
00271 SI_RESOURCE_TOTAL *rt_vec = TSI_Resource_Total_Vector(topcode);
00272
00273 for ( i = 0; i < TSI_Resource_Total_Vector_Size(topcode); ++i ) {
00274 SI_RESOURCE_ID id = SI_RESOURCE_TOTAL_Resource_Id(rt_vec+i);
00275 UINT count = SI_RESOURCE_TOTAL_Total_Used(rt_vec+i);
00276
00277 TI_RES_COUNT_vec(res_counts,id) -= count * factor;
00278 }
00279
00280 for ( i = SI_RR_Length(TSI_Resource_Requirement(topcode));
00281 i > 0;
00282 --i
00283 ) {
00284 if ( SI_BAD_II_SET_MemberP(bad_iis, i) ) {
00285 --TI_RES_COUNT_bad_ii(res_counts, i);
00286 }
00287 }
00288 }
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299 void
00300 TI_RES_COUNT_Add(
00301 TI_RES_COUNT *sum,
00302 TI_RES_COUNT *addend1,
00303 TI_RES_COUNT *addend2
00304 )
00305 {
00306 const INT length = SI_resource_count;
00307 INT i;
00308
00309 for (i = 0; i < length; i++) {
00310 TI_RES_COUNT_vec(sum,i) = TI_RES_COUNT_vec(addend1,i)
00311 + TI_RES_COUNT_vec(addend2,i);
00312 }
00313
00314 for (i = 0; i <= SI_BAD_II_SET_MAX; i++) {
00315 TI_RES_COUNT_bad_ii(sum,i) = TI_RES_COUNT_bad_ii(addend1,i)
00316 + TI_RES_COUNT_bad_ii(addend2,i);
00317 }
00318 }
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 void
00330 TI_RES_COUNT_Subtract(
00331 TI_RES_COUNT *difference,
00332 TI_RES_COUNT *minuend,
00333 TI_RES_COUNT *subtrahend
00334 )
00335 {
00336 const INT length = SI_resource_count;
00337 INT i;
00338
00339 for (i = 0; i < length; i++) {
00340 TI_RES_COUNT_vec(difference,i) = TI_RES_COUNT_vec(minuend,i)
00341 - TI_RES_COUNT_vec(subtrahend,i);
00342 }
00343
00344 for (i = 0; i <= SI_BAD_II_SET_MAX; i++) {
00345 TI_RES_COUNT_bad_ii(difference,i) = TI_RES_COUNT_bad_ii(minuend,i)
00346 - TI_RES_COUNT_bad_ii(subtrahend,i);
00347 }
00348 }
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 void
00360 TI_RES_COUNT_Print(
00361 FILE *fp,
00362 TI_RES_COUNT *res
00363 )
00364 {
00365 BOOL first = TRUE;
00366 SI_RESOURCE_ID i;
00367
00368 fprintf(fp, "TI_RES_COUNT(");
00369 for (i = 0; i < SI_resource_count; i++) {
00370 if (TI_RES_COUNT_vec(res, i) > 0.0) {
00371 if (!first) fprintf(fp, ", ");
00372 fprintf(fp, "%s %G", SI_RESOURCE_ID_Name(i), TI_RES_COUNT_vec(res, i));
00373 if (SI_RESOURCE_ID_Avail_Per_Cycle(i) > 1)
00374 fprintf(fp, "/%d", SI_RESOURCE_ID_Avail_Per_Cycle(i));
00375 first = FALSE;
00376 }
00377 }
00378 fprintf(fp, ")");
00379 fflush(fp);
00380 }
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391 void
00392 TI_RES_COUNT_Emit_Note(
00393 const char *prefix,
00394 FILE *fp,
00395 TI_RES_COUNT *res,
00396 INT ii
00397 )
00398 {
00399 SI_RESOURCE_ID i;
00400 for (i = 0; i < SI_resource_count; i++) {
00401 if (TI_RES_COUNT_vec(res, i) > 0.0 && SI_RESOURCE_ID_Avail_Per_Cycle(i) > 0) {
00402 INT usage = TI_RES_COUNT_vec(res, i) * 100.0 / (SI_RESOURCE_ID_Avail_Per_Cycle(i) * ii);
00403 fprintf(fp, "%s%d %s units ( %d%% of peak )\n",
00404 prefix, (INT) TI_RES_COUNT_vec(res, i), SI_RESOURCE_ID_Name(i), usage);
00405 }
00406 }
00407 }