Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
ti_res_count.c
Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2 of the GNU General Public License as
00007   published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if 
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU General Public License along
00021   with this program; if not, write the Free Software Foundation, Inc., 59
00022   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00023 
00024   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00025   Mountain View, CA 94043, or:
00026 
00027   http://www.sgi.com
00028 
00029   For further information regarding this notice, see:
00030 
00031   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00032 
00033 */
00034 
00035 
00036 
00037 static const char source_file[] = __FILE__;
00038 
00039 #include <stdio.h>
00040 #include <math.h>       /* for ceil */
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 /* Declare the TI_RES_COUNT opaque type (a context for resource counting):
00051  */
00052 struct ti_res_count {
00053   INT32 bad_ii[SI_BAD_II_SET_MAX+1];
00054   double *vec;
00055 };
00056 
00057 /* TI_RES_COUNT accessors:
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  *  TI_RES_COUNT_Alloc
00066  *
00067  *  See interface description
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  *  TI_RES_COUNT_Min_Cycles
00089  *
00090  *  See interface description
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  *  TI_RES_COUNT_Min_II
00115  *
00116  *  See interface description
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  *  TI_RES_COUNT_Add_Op_Resources
00144  *
00145  *  See interface description
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  *  TI_RES_COUNT_Add_Op_Resources_Scaled
00181  *
00182  *  See interface description
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  *  TI_RES_COUNT_Subtract_Op_Resources
00219  *
00220  *  See interface description
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  *  TI_RES_COUNT_Subtract_Op_Resources_Scaled
00256  *
00257  *  See interface description
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  *  TI_RES_COUNT_Add
00294  *
00295  *  See interface description
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  *  TI_RES_COUNT_Subtract
00324  *
00325  *  See interface description
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  *  TI_RES_COUNT_Print
00354  *
00355  *  See interface description
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  *  TI_RES_COUNT_Emit_Note
00386  *
00387  *  See interface description
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines