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
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 #ifndef fb_info_INCLUDED
00056 #define fb_info_INCLUDED
00057
00058 #include "fb_freq.h"
00059
00060 #include <vector>
00061
00062 using namespace std;
00063
00064 #ifdef MONGOOSE_BE
00065
00066 #ifndef mempool_allocator_INCLUDED
00067 #include "mempool_allocator.h"
00068 #endif
00069
00070 #ifndef wn_INCLUDED
00071 #include "wn.h"
00072 #endif
00073
00074 #endif // MONGOOSE_BE
00075
00076
00077
00078
00079
00080 struct FB_Info_Invoke {
00081
00082 FB_FREQ freq_invoke;
00083
00084 FB_Info_Invoke( FB_FREQ invoke)
00085 : freq_invoke( invoke ) {}
00086
00087 FB_Info_Invoke() :
00088
00089
00090
00091
00092
00093
00094
00095 freq_invoke( FB_FREQ_TYPE_UNINIT ) { }
00096
00097 void Print( FILE *fp ) const {
00098 fprintf( fp, "FB---> invoke = " );
00099 freq_invoke.Print( fp );
00100 }
00101 };
00102
00103 struct FB_Info_Branch {
00104
00105 FB_FREQ freq_taken;
00106
00107 FB_FREQ freq_not_taken;
00108
00109
00110 FB_Info_Branch( FB_FREQ taken, FB_FREQ not_taken )
00111 : freq_taken( taken ),
00112 freq_not_taken( not_taken ) {}
00113
00114 #ifdef MONGOOSE_BE
00115 FB_Info_Branch( FB_FREQ taken, FB_FREQ not_taken, OPERATOR opr )
00116 : freq_taken( opr != OPR_FALSEBR ? taken : not_taken ),
00117 freq_not_taken( opr != OPR_FALSEBR ? not_taken : taken ) {
00118
00119 Is_True( opr == OPR_TRUEBR || opr == OPR_FALSEBR
00120 || opr == OPR_IF || opr == OPR_CSELECT,
00121 ( "FB_Info_Branch found unexpected operator" ) );
00122 }
00123 #endif // MONGOOSE_BE
00124
00125
00126
00127
00128
00129 FB_Info_Branch()
00130 : freq_taken( FB_FREQ_TYPE_UNINIT ),
00131 freq_not_taken( FB_FREQ_TYPE_UNINIT ) {}
00132
00133 void Print( FILE *fp ) const {
00134 fprintf( fp, "FB---> taken = " );
00135 freq_taken.Print( fp );
00136 fprintf( fp, ", not_taken = " );
00137 freq_not_taken.Print( fp );
00138 }
00139
00140 FB_FREQ Total() const {
00141 return ( freq_taken + freq_not_taken );
00142 }
00143 };
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 struct FB_Info_Loop {
00167
00168 FB_FREQ freq_zero;
00169 FB_FREQ freq_positive;
00170 FB_FREQ freq_out;
00171 FB_FREQ freq_back;
00172 FB_FREQ freq_exit;
00173 FB_FREQ freq_iterate;
00174
00175 FB_Info_Loop( FB_FREQ zero, FB_FREQ positive, FB_FREQ out, FB_FREQ back,
00176 FB_FREQ exit, FB_FREQ iterate )
00177 : freq_zero( zero ),
00178 freq_positive( positive ),
00179 freq_out( out ),
00180 freq_back( back ),
00181 freq_exit( exit ),
00182 freq_iterate( iterate ) {}
00183
00184 FB_Info_Loop( FB_FREQ zero, FB_FREQ positive, FB_FREQ out, FB_FREQ back )
00185 : freq_zero( zero ),
00186 freq_positive( positive ),
00187 freq_out( out ),
00188 freq_back( back ),
00189 freq_exit( zero + out ),
00190 freq_iterate( positive + back ) {}
00191
00192 FB_Info_Loop( FB_FREQ exit, FB_FREQ iterate )
00193 : freq_zero( FB_FREQ_UNKNOWN ),
00194 freq_positive( FB_FREQ_UNKNOWN ),
00195 freq_out( FB_FREQ_UNKNOWN ),
00196 freq_back( FB_FREQ_UNKNOWN ),
00197 freq_exit( exit ),
00198 freq_iterate( iterate ) {}
00199
00200
00201
00202
00203 FB_Info_Loop()
00204 : freq_zero( FB_FREQ_TYPE_UNINIT ),
00205 freq_positive( FB_FREQ_TYPE_UNINIT ),
00206 freq_out( FB_FREQ_TYPE_UNINIT ),
00207 freq_back( FB_FREQ_TYPE_UNINIT ),
00208 freq_exit( FB_FREQ_TYPE_UNINIT ),
00209 freq_iterate( FB_FREQ_TYPE_UNINIT ) {}
00210
00211
00212
00213 void Print( FILE *fp ) const {
00214 fprintf( fp, "FB---> zero = " );
00215 freq_zero.Print( fp );
00216 fprintf( fp, ", positive = " );
00217 freq_positive.Print( fp );
00218 fprintf( fp, ", out = " );
00219 freq_out.Print( fp );
00220 fprintf( fp, ", back = " );
00221 freq_back.Print( fp );
00222 fprintf( fp, "\n exit = " );
00223 freq_exit.Print( fp );
00224 fprintf( fp, ", iterate = " );
00225 freq_iterate.Print( fp );
00226 }
00227
00228 FB_FREQ Total() const {
00229 return ( freq_exit + freq_iterate );
00230 }
00231
00232 float Loop_lower_scale() const {
00233 FB_FREQ freq_scale = ( freq_zero + freq_positive ) / Total();
00234 if ( freq_scale.Known() )
00235 return freq_scale.Value();
00236 else
00237 return 0.1;
00238 }
00239 };
00240
00241 struct FB_Info_Circuit {
00242
00243 FB_FREQ freq_left;
00244 FB_FREQ freq_right;
00245 FB_FREQ freq_neither;
00246
00247 FB_Info_Circuit( FB_FREQ left, FB_FREQ right, FB_FREQ neither )
00248 : freq_left( left ),
00249 freq_right( right ),
00250 freq_neither( neither ) {}
00251
00252
00253
00254
00255 FB_Info_Circuit()
00256 : freq_left( FB_FREQ_TYPE_UNINIT ),
00257 freq_right( FB_FREQ_TYPE_UNINIT ),
00258 freq_neither( FB_FREQ_TYPE_UNINIT ) {}
00259
00260
00261 void Print( FILE *fp ) const {
00262 fprintf( fp, "FB---> left = " );
00263 freq_left.Print( fp );
00264 fprintf( fp, ", right = " );
00265 freq_right.Print( fp );
00266 fprintf( fp, ", neither = " );
00267 freq_neither.Print( fp );
00268 }
00269
00270 FB_FREQ Total() const {
00271 return ( freq_left + freq_right + freq_neither );
00272 }
00273 };
00274
00275
00276 struct FB_Info_Call {
00277 FB_FREQ freq_entry;
00278 FB_FREQ freq_exit;
00279 BOOL in_out_same;
00280 BOOL dummy_buffer;
00281
00282
00283 FB_Info_Call( FB_FREQ entry, FB_FREQ exit, BOOL same = FALSE )
00284 : freq_entry( entry ),
00285 freq_exit( exit ),
00286 in_out_same( same ) {
00287 Is_True( freq_entry == freq_exit || ! in_out_same,
00288 ( "FEEDBACK::Annot_call: in_out_same failure" ) );
00289 }
00290
00291 FB_Info_Call( FB_FREQ entry_and_exit )
00292 : freq_entry( entry_and_exit ),
00293 freq_exit( entry_and_exit ),
00294 in_out_same( TRUE ) {}
00295
00296
00297
00298
00299 FB_Info_Call() :
00300 freq_entry(FB_FREQ_TYPE_UNINIT),
00301 freq_exit(FB_FREQ_TYPE_UNINIT),
00302 in_out_same(FALSE) {}
00303
00304
00305 void Print( FILE *fp ) const {
00306 fprintf( fp, "FB---> entry = " );
00307 freq_entry.Print( fp );
00308 fprintf( fp, ", exit = " );
00309 freq_exit.Print( fp );
00310 fprintf( fp, ", in_out_same = %c", in_out_same ? 'Y' : 'N' );
00311 }
00312 };
00313
00314
00315 struct FB_Info_Switch {
00316
00317 vector<FB_FREQ> freq_targets;
00318
00319 FB_Info_Switch() {}
00320
00321
00322
00323
00324 FB_Info_Switch( const vector<FB_FREQ>::size_type n )
00325 : freq_targets( vector<FB_FREQ>( n, FB_FREQ_UNINIT ) ) {}
00326
00327 FB_FREQ& operator[] ( const vector<FB_FREQ>::size_type n ) {
00328 if ( n >= freq_targets.size() ) {
00329 freq_targets.insert( freq_targets.end(), n - freq_targets.size() + 1,
00330 FB_FREQ_UNINIT );
00331 }
00332 return freq_targets[n];
00333 }
00334
00335 const FB_FREQ& operator[] ( const vector<FB_FREQ>::size_type n ) const {
00336 return ( n >= freq_targets.size() ? FB_FREQ_UNINIT : freq_targets[n] );
00337 }
00338
00339 vector<FB_FREQ>::size_type size() const {
00340 return freq_targets.size();
00341 }
00342
00343 vector<FB_FREQ>::const_reference back() const {
00344 return freq_targets.back();
00345 }
00346
00347 void pop_back() {
00348 freq_targets.pop_back();
00349 }
00350
00351 void Print( FILE *fp ) const {
00352 fprintf( fp, "FB---> targets = %d", (INT) freq_targets.size() );
00353 for ( INT t = 0; t < freq_targets.size(); t++ ) {
00354 fprintf( fp, ", %d: ", t );
00355 freq_targets[t].Print( fp );
00356 }
00357 }
00358
00359 FB_FREQ Total() const {
00360 vector<FB_FREQ>::const_iterator iter;
00361 FB_FREQ freq = FB_FREQ_ZERO;
00362 for ( iter = freq_targets.begin(); iter != freq_targets.end(); iter++ ) {
00363 freq += *iter;
00364 }
00365 return freq;
00366 }
00367 };
00368
00369
00370
00371 template <class T>
00372 void
00373 FB_Info_Print (const T& info, const char* name, FILE *fp)
00374 {
00375 size_t size = info.size ();
00376
00377 if (size != 0)
00378 fprintf (fp, "%s Profile:\n", name);
00379 for (size_t i = 0; i < size; i++) {
00380 fprintf(fp, "\t%s id = %d\t", name, i);
00381 info[i].Print (fp);
00382 fputc ('\n', fp);
00383 }
00384 }
00385
00386
00387
00388
00389 #ifdef MONGOOSE_BE
00390
00391 typedef vector<FB_Info_Invoke, mempool_allocator<FB_Info_Invoke> >
00392 FB_Invoke_Vector;
00393 typedef vector<FB_Info_Branch, mempool_allocator<FB_Info_Branch> >
00394 FB_Branch_Vector;
00395 typedef vector<FB_Info_Loop, mempool_allocator<FB_Info_Loop> >
00396 FB_Loop_Vector;
00397 typedef vector<FB_Info_Circuit, mempool_allocator<FB_Info_Circuit> >
00398 FB_Circuit_Vector;
00399 typedef vector<FB_Info_Call, mempool_allocator<FB_Info_Call> >
00400 FB_Call_Vector;
00401 typedef vector<FB_Info_Switch, mempool_allocator<FB_Info_Switch> >
00402 FB_Switch_Vector;
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413 #define FB_IO_ESCAPE_EDGES_MAX 3
00414
00415 enum FB_EDGE_TYPE {
00416 FB_EDGE_UNINIT = 0,
00417 FB_EDGE_INCOMING = 1,
00418 FB_EDGE_OUTGOING = 2,
00419 FB_EDGE_ENTRY_OUTGOING = 3,
00420 FB_EDGE_BRANCH_TAKEN = 4,
00421 FB_EDGE_BRANCH_NOT_TAKEN = 5,
00422 FB_EDGE_LOOP_ZERO = 6,
00423 FB_EDGE_LOOP_POSITIVE = 7,
00424 FB_EDGE_LOOP_OUT = 8,
00425 FB_EDGE_LOOP_BACK = 9,
00426 FB_EDGE_LOOP_EXIT = 10,
00427 FB_EDGE_LOOP_ITERATE = 11,
00428 FB_EDGE_CIRCUIT_LEFT = 12,
00429 FB_EDGE_CIRCUIT_RIGHT = 13,
00430 FB_EDGE_CIRCUIT_NEITHER = 14,
00431 FB_EDGE_CALL_INCOMING = 15,
00432 FB_EDGE_CALL_OUTGOING = 16,
00433 FB_EDGE_CALL_INOUTSAME = 17,
00434 FB_EDGE_IO_OUTGOING = 18,
00435 FB_EDGE_IO_ESCAPE_BASE = 19,
00436 FB_EDGE_SWITCH_DEFAULT = 22,
00437 FB_EDGE_SWITCH_BASE = 23
00438 };
00439
00440
00441
00442
00443 #define FB_EDGE_IO_ESCAPE(br) ( FB_EDGE_TYPE( FB_EDGE_IO_ESCAPE_BASE + (br) ) )
00444
00445 #define FB_EDGE_SWITCH(br) ( FB_EDGE_TYPE( FB_EDGE_SWITCH_BASE + (br) ) )
00446 #define FB_EDGE_SWITCH_INDEX(typ) ( INT32( (typ) - FB_EDGE_SWITCH_BASE + 1 ) )
00447
00448 #define FB_EDGE_TYPE_NAME_LENGTH 20 // buffer length required for
00449
00450
00451 extern const char *FB_EDGE_NAMES[];
00452
00453 void FB_EDGE_TYPE_fprintf( FILE *fp, const FB_EDGE_TYPE fb_type );
00454 INT FB_EDGE_TYPE_sprintf( char *buffer, const FB_EDGE_TYPE fb_type );
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 #define fb_opr_cases_invoke \
00466 case OPR_LABEL: \
00467 case OPR_GOTO: \
00468 case OPR_MSTORE: \
00469 case OPR_FUNC_ENTRY: \
00470 case OPR_ALTENTRY: \
00471 case OPR_RETURN: \
00472 case OPR_RETURN_VAL
00473
00474
00475 inline bool FB_valid_opr_invoke(const WN *wn) {
00476 OPERATOR opr = WN_operator( wn );
00477 switch ( opr ) {
00478 fb_opr_cases_invoke:
00479 return true;
00480 case OPR_PRAGMA:
00481 return ( WN_pragma( wn ) == WN_PRAGMA_PREAMBLE_END );
00482 default:
00483 return false;
00484 }
00485 }
00486
00487
00488
00489
00490
00491
00492
00493
00494 #define fb_opr_cases_branch \
00495 case OPR_TRUEBR: \
00496 case OPR_FALSEBR: \
00497 case OPR_IF: \
00498 case OPR_CSELECT
00499
00500 inline bool FB_valid_opr_branch(const WN *wn) {
00501 OPERATOR opr = WN_operator( wn );
00502 switch ( opr ) {
00503 fb_opr_cases_branch:
00504 return true;
00505 default:
00506 return false;
00507 }
00508 }
00509
00510
00511
00512
00513 #define fb_opr_cases_loop \
00514 case OPR_DO_LOOP: \
00515 case OPR_WHILE_DO: \
00516 case OPR_DO_WHILE
00517
00518 inline bool FB_valid_opr_loop(const WN *wn) {
00519 OPERATOR opr = WN_operator( wn );
00520 switch ( opr ) {
00521 fb_opr_cases_loop:
00522 return true;
00523 default:
00524 return false;
00525 }
00526 }
00527
00528
00529
00530
00531
00532
00533
00534 #define fb_opr_cases_circuit \
00535 case OPR_CAND: \
00536 case OPR_CIOR
00537
00538 inline bool FB_valid_opr_circuit(const WN *wn) {
00539 OPERATOR opr = WN_operator( wn );
00540 switch ( opr ) {
00541 fb_opr_cases_circuit:
00542 return true;
00543 default:
00544 return false;
00545 }
00546 }
00547
00548
00549
00550
00551
00552 #define fb_opr_cases_call \
00553 case OPR_PICCALL: \
00554 case OPR_CALL: \
00555 case OPR_ICALL: \
00556 case OPR_INTRINSIC_CALL: \
00557 case OPR_IO
00558
00559
00560 inline bool FB_valid_opr_call(const WN *wn) {
00561 OPERATOR opr = WN_operator( wn );
00562 switch ( opr ) {
00563 fb_opr_cases_call:
00564 return true;
00565 default:
00566 return false;
00567 }
00568 }
00569
00570
00571
00572
00573
00574
00575
00576 #define fb_opr_cases_switch \
00577 case OPR_SWITCH: \
00578 case OPR_COMPGOTO: \
00579 case OPR_XGOTO
00580
00581 inline bool FB_valid_opr_switch (const WN *wn) {
00582 OPERATOR opr = WN_operator( wn );
00583 switch ( opr ) {
00584 fb_opr_cases_switch:
00585 return true;
00586 default:
00587 return false;
00588 }
00589 }
00590
00591 #endif // MONGOOSE_BE
00592
00593
00594 #endif
00595
00596
00597
00598
00599
00600
00601
00602