Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
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 //-*-c++-*- 00037 // ==================================================================== 00038 // ==================================================================== 00039 // 00040 // 00041 // Description: 00042 // 00043 // During instrumentation, certain events associated with program 00044 // control flow (such as the number of times a particular branch is 00045 // taken, or not taken) are counted. During subsequent compilations, 00046 // this data may be retrieved and used to guide optimization decisions. 00047 // 00048 // Frequencies are stored as float in order to permit scaling. 00049 // 00050 // A frequency value is stored as a FB_FREQ data type, which can have 00051 // one of the following values: 00052 // - an EXACT nonnegative float value 00053 // - a GUESS nonnegative float value 00054 // - UNKNOWN - an unknown frequency; its value may be computable from 00055 // other frequency data 00056 // - UNINIT - an uninitialized frequency 00057 // - ERROR - the result of dividing by zero, or subtracting a larger 00058 // from a smaller frequency value. 00059 // 00060 // EXACT values give an exactly correct count of the number of times 00061 // that a particular edge was traveled during the program's 00062 // instrumentated execution. GUESS values are educated estimates of 00063 // the count. Whenever a piece of code is cloned (eg: IPA; also the 00064 // test condition of a WHILE_DO loop is cloned during lowering), the 00065 // code's frequencies are scaled, and EXACT values are converted to 00066 // GUESSes. 00067 // 00068 // Sometimes dead branch elimination and frequency propagation will 00069 // enable GUESSes to be replaced later by EXACT counts, and UNKNOWN 00070 // values to be replaced by EXACT and GUESS values. 00071 // 00072 // Normally, ERROR and UNINIT frequencies should only be encountered 00073 // locally. 00074 // 00075 // Operations ( +, - , * , /, +=, -=, *=, /=, ==, !=, <, >, <=, >= ) 00076 // are provided to combine, compare, and display frequencies. * is 00077 // assumed to be scaling, so EXACT values are replaced by GUESSes. 00078 // Comparison operations do not distinguish between GUESS and EXACT 00079 // values. 00080 // 00081 // ==================================================================== 00082 // ==================================================================== 00083 00084 #ifndef fb_freq_INCLUDED 00085 #define fb_freq_INCLUDED 00086 00087 #include "defs.h" 00088 #ifndef ERRORS_INCLUDED 00089 #include "errors.h" 00090 #endif 00091 00092 // ==================================================================== 00093 // FB_FREQ_TYPE - frequency types 00094 // ==================================================================== 00095 00096 // The FB_FREQ_TYPE integer values are chosen to satisfy two rules: 00097 // (1) When two FB_FREQs are combined, the resulting FB_FREQ has normally 00098 // FB_FREQ_TYPE equal to the minimum of those of the two FB_FREQ 00099 // addends; and 00100 // (2) EXACTness and KNOWNness can be ascertained by comparing the 00101 // FB_FREQ_TYPE to zero. 00102 00103 enum FB_FREQ_TYPE { 00104 FB_FREQ_TYPE_EXACT = 1, 00105 FB_FREQ_TYPE_GUESS = 0, 00106 FB_FREQ_TYPE_UNKNOWN = -1, 00107 FB_FREQ_TYPE_UNINIT = -2, 00108 FB_FREQ_TYPE_ERROR = -3 00109 }; 00110 00111 #define FB_FREQ_TYPE_COMBINE( type1, type2 ) \ 00112 ( (type1) > (type2) ? (type2) : (type1) ) 00113 #define FB_FREQ_TYPE_BETTER( type1, type2 ) ( (type1) > (type2) ) 00114 00115 #define FB_FREQ_TYPE_IS_EXACT( type ) ( (type) > 0 ) 00116 #define FB_FREQ_TYPE_IS_GUESS( type ) ( (type) == 0 ) 00117 #define FB_FREQ_TYPE_IS_KNOWN( type ) ( (type) >= 0 ) 00118 #define FB_FREQ_TYPE_NOT_KNOWN( type ) ( (type) < 0 ) 00119 #define FB_FREQ_TYPE_INITIALIZED( type ) ( (type) >= FB_FREQ_TYPE_UNKNOWN ) 00120 00121 #define FB_FREQ_TYPE_IS_VALID( type ) \ 00122 ( (type) >= FB_FREQ_TYPE_ERROR && (type) <= FB_FREQ_TYPE_EXACT ) 00123 00124 // ==================================================================== 00125 // FB_FREQ - frequency values 00126 // ==================================================================== 00127 00128 // To account for round-off error, x == y iff x > y (1 - epsilon) 00129 // and y > x (1 - epsilon) 00130 00131 const float FB_FREQ_EPSILON = 0.0001; 00132 00133 class FB_FREQ { 00134 private: 00135 00136 FB_FREQ_TYPE _type; 00137 float _value; 00138 00139 // In order to simplify FB_FREQ operations, two internal restrictions 00140 // are imposed: 00141 // (1) If _type >= 0, then _value >= 0.0; and 00142 // (2) If _type < 0, then _value == (float) _type. 00143 00144 // Private constructor, for binary operations 00145 FB_FREQ( FB_FREQ_TYPE type, float value ) 00146 : _type( type ), _value( value ) { } 00147 00148 public: 00149 00150 // Constructor methods 00151 00152 FB_FREQ() 00153 : _type( FB_FREQ_TYPE_UNINIT ), 00154 _value( (float) FB_FREQ_TYPE_UNINIT ) {} 00155 00156 FB_FREQ( float value, bool exact ) 00157 : _type( exact ? FB_FREQ_TYPE_EXACT : FB_FREQ_TYPE_GUESS ), 00158 _value( value ) 00159 { Is_True( value >= 0.0, ( "FB_FREQ: negative value %f", value ) ); } 00160 00161 FB_FREQ( INT64 value ) 00162 : _type( FB_FREQ_TYPE_EXACT ), 00163 _value( (float) value ) 00164 { Is_True( value >= 0, ( "FB_FREQ: negative value %lld", value ) ); } 00165 00166 FB_FREQ( FB_FREQ_TYPE type ) 00167 : _type( type ), 00168 _value( type >= 0 ? 0.0 : (float) type ) { 00169 Is_True( FB_FREQ_TYPE_IS_VALID( type ), 00170 ( "FB_FREQ: invalid type %d", type ) ); 00171 } 00172 00173 // Member access methods 00174 00175 float Value() const { return _value; } 00176 00177 // Boolean tests 00178 00179 bool Known() const { return FB_FREQ_TYPE_IS_KNOWN( _type ); } 00180 bool Guess() const { return FB_FREQ_TYPE_IS_GUESS( _type ); } 00181 bool Exact() const { return FB_FREQ_TYPE_IS_EXACT( _type ); } 00182 bool Uninitialized() const { return ( _type == FB_FREQ_TYPE_UNINIT ); } 00183 bool Initialized() const { return FB_FREQ_TYPE_INITIALIZED( _type ); } 00184 bool Error() const { return ( _type == FB_FREQ_TYPE_ERROR ); } 00185 bool Zero() const { return ( _value < FB_FREQ_EPSILON && 00186 _value > - FB_FREQ_EPSILON ); } 00187 00188 bool Better( const FB_FREQ freq ) const { 00189 return FB_FREQ_TYPE_BETTER( _type, freq._type ); 00190 } 00191 00192 // Operators 00193 00194 FB_FREQ operator+= ( const FB_FREQ freq ) { 00195 _type = FB_FREQ_TYPE_COMBINE( _type, freq._type ); 00196 if ( FB_FREQ_TYPE_NOT_KNOWN( _type ) ) 00197 _value = (float) _type; 00198 else 00199 _value += freq._value; 00200 return *this; 00201 } 00202 00203 FB_FREQ operator-= ( const FB_FREQ freq ) { 00204 _type = FB_FREQ_TYPE_COMBINE( _type, freq._type ); 00205 if ( FB_FREQ_TYPE_NOT_KNOWN( _type ) ) 00206 _value = (float) _type; 00207 else { 00208 _value -= freq._value; 00209 if ( _value < 0 ) 00210 if ( - _value < FB_FREQ_EPSILON 00211 || - _value < FB_FREQ_EPSILON * freq._value ) 00212 _value = 0; 00213 else { 00214 DevWarn( "FB_FREQ: subtraction of larger from smaller value" ); 00215 _type = FB_FREQ_TYPE_ERROR; 00216 _value = (float) _type; 00217 } 00218 } 00219 return *this; 00220 } 00221 00222 FB_FREQ operator*= ( const FB_FREQ freq ) { 00223 if ( Zero() && Exact() ) 00224 ; // Nothing to do 00225 else if ( freq.Zero() && freq.Exact() ) { 00226 _type = FB_FREQ_TYPE_EXACT; 00227 _value = 0.0; 00228 } else { 00229 _type = FB_FREQ_TYPE_COMBINE( _type, freq._type ); 00230 if ( FB_FREQ_TYPE_NOT_KNOWN( _type ) ) 00231 _value = (float) _type; 00232 else 00233 _value *= freq._value; 00234 } 00235 return *this; 00236 } 00237 00238 // All scale factors are assumed to be guesses 00239 FB_FREQ operator*= ( const float scale ) { 00240 Is_True ( scale >= 0.0, ( "FB_FREQ: negative scale %f", scale ) ); 00241 return ( *this *= FB_FREQ( FB_FREQ_TYPE_GUESS, scale ) ); 00242 } 00243 00244 // Division used to determine scale or probability. 00245 // Results other than exact 0s and 1s are assumed to be guesses. 00246 FB_FREQ operator/= ( const FB_FREQ freq ) { 00247 if ( Zero() && Exact() ) 00248 ; // Nothing to do 00249 else if ( freq.Zero() ) { 00250 DevWarn("FB_FREQ: division by zero"); 00251 _type = FB_FREQ_TYPE_ERROR; 00252 _value = (float) _type; 00253 } else { 00254 _type = FB_FREQ_TYPE_COMBINE( _type, freq._type ); 00255 if ( FB_FREQ_TYPE_NOT_KNOWN( _type ) ) 00256 _value = (float) _type; 00257 else { 00258 if ( _value != freq._value ) 00259 _type = FB_FREQ_TYPE_COMBINE( _type, FB_FREQ_TYPE_GUESS ); 00260 _value /= freq._value; 00261 } 00262 } 00263 return *this; 00264 } 00265 00266 // All scale factors are assumed to be guesses 00267 FB_FREQ operator/= ( const float scale ) { 00268 Is_True ( scale >= 0.0, ( "FB_FREQ: negative scale %f", scale ) ); 00269 return ( *this /= FB_FREQ( FB_FREQ_TYPE_GUESS, scale ) ); 00270 } 00271 00272 // Binary operations 00273 00274 friend FB_FREQ operator+ ( const FB_FREQ freq1, const FB_FREQ freq2 ) { 00275 FB_FREQ_TYPE type = FB_FREQ_TYPE_COMBINE( freq1._type, freq2._type ); 00276 if ( FB_FREQ_TYPE_NOT_KNOWN( type ) ) 00277 return FB_FREQ( type ); 00278 return FB_FREQ( type, freq1._value + freq2._value ); 00279 } 00280 00281 friend FB_FREQ operator- ( const FB_FREQ freq1, const FB_FREQ freq2 ) { 00282 FB_FREQ_TYPE type = FB_FREQ_TYPE_COMBINE( freq1._type, freq2._type ); 00283 if ( FB_FREQ_TYPE_NOT_KNOWN( type ) ) 00284 return FB_FREQ( type ); 00285 float value = freq1._value - freq2._value; 00286 if ( value >= 0 ) 00287 return FB_FREQ( type, value ); 00288 if ( - value < FB_FREQ_EPSILON 00289 || - value < freq2._value * FB_FREQ_EPSILON ) 00290 return FB_FREQ( type, 0 ); 00291 DevWarn( "FB_FREQ: subtraction of larger from smaller value" ); 00292 return FB_FREQ( FB_FREQ_TYPE_ERROR ); 00293 } 00294 00295 friend FB_FREQ operator* ( const FB_FREQ freq1, const FB_FREQ freq2 ) { 00296 if ( ( freq1.Zero() && freq1.Exact() ) || 00297 ( freq2.Zero() && freq2.Exact() ) ) 00298 return FB_FREQ( FB_FREQ_TYPE_EXACT, 0.0 ); 00299 FB_FREQ_TYPE type = FB_FREQ_TYPE_COMBINE( freq1._type, freq2._type ); 00300 if ( FB_FREQ_TYPE_NOT_KNOWN( type ) ) 00301 return FB_FREQ( type ); 00302 return FB_FREQ( type, freq1._value * freq2._value ); 00303 } 00304 00305 // All scale factors are assumed to be guesses 00306 friend FB_FREQ operator* ( const FB_FREQ freq, const float scale ) { 00307 Is_True ( scale >= 0.0, ( "FB_FREQ: negative scale %f", scale ) ); 00308 return ( freq * FB_FREQ( FB_FREQ_TYPE_GUESS, scale ) ); 00309 } 00310 00311 // Division used to determine scale or probability. 00312 // Results other than exact 0s and 1s are assumed to be guesses. 00313 friend FB_FREQ operator/ ( const FB_FREQ freq1, const FB_FREQ freq2 ) { 00314 if ( freq1.Zero() && freq1.Exact() ) 00315 return FB_FREQ( FB_FREQ_TYPE_EXACT, 0.0 ); 00316 if ( freq2.Zero() ) { 00317 DevWarn("FB_FREQ: division by zero"); 00318 return FB_FREQ( FB_FREQ_TYPE_ERROR ); 00319 } 00320 FB_FREQ_TYPE type = FB_FREQ_TYPE_COMBINE( freq1._type, freq2._type ); 00321 if ( FB_FREQ_TYPE_NOT_KNOWN( type ) ) 00322 return FB_FREQ( type ); 00323 if ( freq1._value != freq2._value ) 00324 type = FB_FREQ_TYPE_COMBINE( type, FB_FREQ_TYPE_GUESS ); 00325 float value = freq1._value / freq2._value; 00326 return FB_FREQ( type, value ); 00327 } 00328 00329 // All scale factors are assumed to be guesses 00330 friend FB_FREQ operator/ ( const FB_FREQ freq, float scale ) { 00331 Is_True ( scale >= 0.0, ( "FB_FREQ: negative scale %f", scale ) ); 00332 return ( freq / FB_FREQ( FB_FREQ_TYPE_GUESS, scale ) ); 00333 } 00334 00335 friend bool operator== ( const FB_FREQ freq1, const FB_FREQ freq2 ) { 00336 if ( freq1._value > freq2._value ) 00337 return ( freq1._value < FB_FREQ_EPSILON 00338 || freq1._value * ( 1 - FB_FREQ_EPSILON ) < freq2._value ); 00339 else if ( freq1._value < freq2._value ) 00340 return ( freq2._value < FB_FREQ_EPSILON 00341 || freq2._value * ( 1 - FB_FREQ_EPSILON ) < freq1._value ); 00342 else return true; 00343 } 00344 00345 friend bool operator!= ( const FB_FREQ freq1, const FB_FREQ freq2 ) { 00346 if ( freq1._value > freq2._value ) 00347 return ( freq1._value >= FB_FREQ_EPSILON 00348 && freq1._value * ( 1 - FB_FREQ_EPSILON ) >= freq2._value ); 00349 else if ( freq1._value < freq2._value ) 00350 return ( freq2._value >= FB_FREQ_EPSILON 00351 && freq2._value * ( 1 - FB_FREQ_EPSILON ) >= freq1._value ); 00352 else return false; 00353 } 00354 00355 friend bool operator> ( const FB_FREQ freq1, const FB_FREQ freq2 ) { 00356 return ( freq1._value > freq2._value ); 00357 } 00358 00359 friend bool operator< ( const FB_FREQ freq1, const FB_FREQ freq2 ) { 00360 return ( freq1._value < freq2._value ); 00361 } 00362 00363 friend bool operator<= ( const FB_FREQ freq1, const FB_FREQ freq2 ) { 00364 return ( (freq1._value < freq2._value) || (freq1 == freq2) ); 00365 } 00366 00367 // Printing methods 00368 00369 void Print( FILE *fp ) const { 00370 switch ( _type ) { 00371 case FB_FREQ_TYPE_EXACT: 00372 fprintf( fp, "%g!", _value ); 00373 break; 00374 case FB_FREQ_TYPE_GUESS: 00375 fprintf( fp, "%g?", _value ); 00376 break; 00377 case FB_FREQ_TYPE_UNKNOWN: 00378 fprintf( fp, "unknown" ); 00379 break; 00380 case FB_FREQ_TYPE_UNINIT: 00381 fprintf( fp, "uninitialized" ); 00382 break; 00383 case FB_FREQ_TYPE_ERROR: 00384 fprintf( fp, "error" ); 00385 break; 00386 default: 00387 Is_True( FALSE, ("FB_FREQ: Unexpected type %d", _type )); 00388 break; 00389 } 00390 } 00391 00392 INT Sprintf( char *buffer ) const { 00393 INT length = 0; 00394 switch ( _type ) { 00395 case FB_FREQ_TYPE_EXACT: 00396 length = sprintf( buffer, "%g!", _value ); 00397 break; 00398 case FB_FREQ_TYPE_GUESS: 00399 length = sprintf( buffer, "%g?", _value ); 00400 break; 00401 case FB_FREQ_TYPE_UNKNOWN: 00402 length = sprintf( buffer, "unknown" ); 00403 break; 00404 case FB_FREQ_TYPE_UNINIT: 00405 length = sprintf( buffer, "uninitialized" ); 00406 break; 00407 case FB_FREQ_TYPE_ERROR: 00408 length = sprintf( buffer, "error" ); 00409 break; 00410 default: 00411 Is_True( FALSE, ("FB_FREQ: Unexpected type %d", _type )); 00412 break; 00413 } 00414 return length; 00415 } 00416 }; 00417 00418 00419 // Some FB_FREQ constants. For unknown and uninitialized frequencies, 00420 // use these instead of invoking an FB_FREQ constructor. 00421 00422 const FB_FREQ FB_FREQ_ZERO( 0.0, true /*EXACT*/ ); 00423 const FB_FREQ FB_FREQ_UNKNOWN( FB_FREQ_TYPE_UNKNOWN ); 00424 const FB_FREQ FB_FREQ_UNINIT( FB_FREQ_TYPE_UNINIT ); 00425 const FB_FREQ FB_FREQ_ERROR( FB_FREQ_TYPE_ERROR ); 00426 00427 // ==================================================================== 00428 00429 #endif //#ifndef fb_freq_INCLUDED