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 #include "bb.h"
00048 #include "cg.h"
00049 #include "defs.h"
00050 #include "cg_region.h"
00051 #include "label_util.h"
00052 #include "edge_profile.h"
00053 #include "symtab.h"
00054 #include "data_layout.h"
00055 #include "symtab_access.h"
00056 #include "cg_flags.h"
00057 #include "vt_region.h"
00058 #include "tracing.h"
00059 #include "instr_reader.h"
00060 #include "dump_feedback.h"
00061 #include "freq.h"
00062 #include "ipfec_defs.h"
00063 #include "gra_live.h"
00064 #include "region.h"
00065 #include "region_bb_util.h"
00066 #include "region_update.h"
00067 #include "region_verify.h"
00068 #include <ipfec_options.h>
00069
00070 WN *
00071 Gen_Call_Shell( char *name, TYPE_ID rtype, INT32 argc )
00072 {
00073 TY_IDX ty = Make_Function_Type( MTYPE_To_TY( rtype ) );
00074 ST *st = Gen_Intrinsic_Function( ty, name );
00075
00076 Clear_PU_no_side_effects( Pu_Table[ST_pu( st )] );
00077 Clear_PU_is_pure( Pu_Table[ST_pu( st )] );
00078 Set_PU_no_delete( Pu_Table[ST_pu( st )] );
00079
00080 WN *wn_call = WN_Call( rtype, MTYPE_V, argc, st );
00081
00082 WN_Set_Call_Default_Flags( wn_call );
00083 return wn_call;
00084 }
00085
00086 WN *
00087 Gen_Call( char *name, WN *arg1, WN *arg2, TYPE_ID rtype )
00088 {
00089 WN *call = Gen_Call_Shell( name, rtype, 2 );
00090 WN_actual( call, 0 ) = Gen_Param( arg1, WN_PARM_BY_VALUE );
00091 WN_actual( call, 1 ) = Gen_Param( arg2, WN_PARM_BY_VALUE );
00092 return call;
00093 }
00094
00095 WN *
00096 Gen_Call( char *name, WN *arg1, TYPE_ID rtype )
00097 {
00098 WN *call = Gen_Call_Shell( name, rtype, 1 );
00099 WN_actual( call, 0 ) = Gen_Param( arg1, WN_PARM_BY_VALUE );
00100 return call;
00101 }
00102
00103 void CG_Edge_Profile_Instrument( CGRIN* cgrin,PROFILE_PHASE phase )
00104 {
00105
00106
00107
00108 extern char* Instrumentation_File_Name;
00109 if (Instrumentation_File_Name != NULL)
00110 Instru_File_Name = Instrumentation_File_Name;
00111 if ( Instru_File_Name == NULL )
00112 {
00113 DevWarn( "not specify the feedback file!use default feedback file\n" );
00114 Instru_File_Name = Src_File_Name;
00115 }
00116 PU_PROFILE_HANDLES fb_handles;
00117 EDGE_PROFILE edge_prof( cgrin,TRUE, phase, fb_handles );
00118 edge_prof.CG_Instrument( );
00119 }
00120
00121 void CG_Edge_Profile_Annotation( CGRIN* cgrin,PROFILE_PHASE phase )
00122 {
00123
00124
00125 char* srcfile_pu_name = CXX_NEW_ARRAY( char, strlen( Src_File_Name ) +
00126 strlen( "/" ) + strlen( Cur_PU_Name ) + 1, &MEM_local_nz_pool );
00127 strcpy( srcfile_pu_name,Src_File_Name );
00128 strcat( srcfile_pu_name,"/" );
00129 strcat( srcfile_pu_name,Cur_PU_Name);
00130
00131 FREQ_Compute_BB_Frequencies( );
00132 PU_PROFILE_HANDLES fb_handles
00133 = Get_CG_PU_Profile( srcfile_pu_name, Feedback_File_Info[phase] );
00134 if( fb_handles.empty( ) )
00135 {
00136
00137 DevWarn( "Cannot find expected feedback data - function not called?" );
00138 CG_PU_Has_Feedback = FALSE;
00139 FREQ_Compute_BB_Frequencies( );
00140 Compute_Edge_Freq_Base_Prob( );
00141 return;
00142 }
00143
00144 FREQ_freqs_computed = TRUE;
00145 CG_PU_Has_Feedback = TRUE;
00146
00147 edge_done= TRUE;
00148
00149 if( Get_Trace( TP_A_PROF,TT_PROF_FEEDBACK_DUMP ) )
00150 {
00151 Dump_Fb_Data( fb_handles );
00152 DevWarn( "find expected feedback data!" );
00153 }
00154 Init_CFG( );
00155 EDGE_PROFILE edge_prof( cgrin,FALSE, phase, fb_handles );
00156 edge_prof.CG_Annotate( );
00157 }
00158
00159 void EDGE_PROFILE::CG_Instrument( )
00160 {
00161
00162
00163 int BB_Count;
00164 if ( ( Curr_PU_BB_Count( ) <= 1 )
00165 && ( ( BB_xfer_op( _pu_first_bb ) == NULL )
00166 ||( OP_code( BB_xfer_op( _pu_first_bb ) ) == TOP_br_ret )
00167 ||( OP_code( BB_xfer_op( _pu_first_bb ) ) == TOP_brp_ret ) ) )
00168 return;
00169 if( Get_Trace( TP_A_PROF,TT_PROF_CFG ) )
00170 draw_global_cfg( "before edge profile" );
00171 Prepare_Instrument( );
00172
00173
00174
00175 _instrument_count = 0;
00176
00177 for( BB* bb =_pu_last_bb; bb != NULL;
00178 bb = BB_prev( bb ) )
00179 {
00180 if(BB_Is_For_Instru(bb))
00181 CG_Instrument_Node( bb );
00182 }
00183
00184 Instrument_Entry( );
00185 if( Get_Trace( TP_A_PROF,TT_PROF_CFG ) )
00186 {
00187 FREQ_Check_Consistency( "edge profile instrument" );
00188 draw_global_cfg( "after edge profile" );
00189 }
00190 }
00191
00192
00193
00194
00195
00196 void EDGE_PROFILE::Instrument_Entry( )
00197 {
00198 char* outputfile_name = Instru_File_Name;
00199 PU_Has_Calls = TRUE;
00200 BB* bb = _pu_first_bb;
00201 BB_LIST *elist;
00202 for ( elist = Entry_BB_Head; elist != NULL; elist = BB_LIST_rest(elist) )
00203 {
00204 bb = BB_LIST_first(elist);
00205 if ( bb != NULL && !BB_call( bb ) )
00206 {
00207 op* op = BB_xfer_op( bb );
00208 if ( op != NULL )
00209 {
00210 BBLIST* edge = BB_succs( bb );
00211 INT32 bblist_len =BBlist_Len( edge );
00212 while ( edge != NULL && bblist_len-- )
00213 {
00214 BBLIST* nedge = edge;
00215 edge = BBLIST_next( edge );
00216
00217
00218 BB* target_bb = BBLIST_item( nedge );
00219 BB* instru_init_call_bb = Gen_Call_BB( INSTR_INIT_NAME,
00220 outputfile_name,_phase,0 );
00221 Set_BB_profile_added(instru_init_call_bb);
00222 BB* instru_pu_init_call_bb = Gen_Call_BB( PU_INIT_NAME,
00223 _srcfile_pu_name,_instrument_count,0 );
00224 Set_BB_profile_added(instru_pu_init_call_bb);
00225 LABEL_IDX instru_bb_label = Gen_Label_For_BB( instru_init_call_bb );
00226
00227
00228 LABEL_IDX tgt_label;
00229 if ( Get_Label_BB( Get_Br_Op_Tgt_Label( op ) ) == target_bb )
00230 tgt_label = Get_Br_Op_Tgt_Label( op );
00231 else
00232 tgt_label = Gen_Label_For_BB( target_bb );
00233
00234 if( BB_next( bb ) == target_bb )
00235 {
00236 Insert_BB( instru_init_call_bb,bb );
00237 Insert_BB( instru_pu_init_call_bb,instru_init_call_bb );
00238
00239
00240 if (IPFEC_Enable_Region_Formation &&
00241 _phase != PROFILE_PHASE_BEFORE_REGION)
00242 {
00243 REGIONAL_CFG_NODE* node = Regional_Cfg_Node(bb);
00244 REGION* reg = node->Home_Region();
00245 REGIONAL_CFG* regional_cfg = reg->Regional_Cfg();
00246
00247 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
00248 float original_prob = Prob_Local(bb,target_bb);
00249 RGN_Gen_And_Insert_Node(instru_init_call_bb,bb,
00250 target_bb,regional_cfg);
00251 RGN_Gen_And_Insert_Node(instru_pu_init_call_bb,
00252 instru_init_call_bb,target_bb,regional_cfg);
00253 RGN_Unlink_Pred_Succ( bb,target_bb,regional_cfg );
00254 RGN_Link_Pred_Succ_With_Prob( bb,instru_init_call_bb,
00255 original_prob,regional_cfg );
00256 RGN_Link_Pred_Succ_With_Prob( instru_init_call_bb,
00257 instru_pu_init_call_bb,1.0,regional_cfg);
00258 RGN_Link_Pred_Succ_With_Prob( instru_pu_init_call_bb,target_bb,
00259 1.0 );
00260
00261 BB_freq( instru_init_call_bb ) = original_freq;
00262 BB_freq( instru_pu_init_call_bb ) = original_freq;
00263 }else
00264 {
00265 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
00266 float original_prob = Prob_Local(bb,target_bb);
00267 Unlink_Pred_Succ( bb,target_bb );
00268 Link_Pred_Succ( bb,instru_init_call_bb );
00269 Link_Pred_Succ( instru_init_call_bb,instru_pu_init_call_bb );
00270 Link_Pred_Succ( instru_pu_init_call_bb,target_bb );
00271
00272 BB_freq( instru_init_call_bb ) = original_freq;
00273 BB_freq( instru_pu_init_call_bb ) = original_freq;
00274 Set_Prob( bb,instru_init_call_bb,original_prob );
00275 Set_Prob( instru_init_call_bb,instru_pu_init_call_bb, 1.0);
00276 Set_Prob( instru_pu_init_call_bb,target_bb,1.0 );
00277 }
00278 }else
00279 {
00280 BB* goto_bb = Gen_BB( );
00281 Set_BB_profile_added(goto_bb);
00282 BB* old_last_bb = Get_Pu_Last_BB( );
00283 Set_Pu_Last_BB( goto_bb );
00284
00285 Insert_BB( instru_init_call_bb,old_last_bb );
00286 Insert_BB( instru_pu_init_call_bb,instru_init_call_bb );
00287 Insert_BB( goto_bb,instru_pu_init_call_bb );
00288 Add_Goto( goto_bb, target_bb );
00289
00290
00291 if (IPFEC_Enable_Region_Formation &&
00292 _phase != PROFILE_PHASE_BEFORE_REGION)
00293 {
00294 REGIONAL_CFG_NODE* node = Regional_Cfg_Node(bb);
00295 REGION* reg = node->Home_Region();
00296 REGIONAL_CFG* regional_cfg = reg->Regional_Cfg();
00297
00298 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
00299 float original_prob = Prob_Local(bb,target_bb);
00300
00301 RGN_Gen_And_Insert_Node(instru_init_call_bb,bb,
00302 target_bb,regional_cfg);
00303 RGN_Gen_And_Insert_Node(instru_pu_init_call_bb,
00304 instru_init_call_bb,target_bb,regional_cfg);
00305 RGN_Gen_And_Insert_Node(goto_bb,instru_pu_init_call_bb,
00306 target_bb,regional_cfg);
00307 RGN_Unlink_Pred_Succ( bb,target_bb );
00308 RGN_Link_Pred_Succ_With_Prob( bb,instru_init_call_bb,
00309 original_prob, regional_cfg );
00310 RGN_Link_Pred_Succ_With_Prob( instru_init_call_bb,
00311 instru_pu_init_call_bb, 1.0,regional_cfg );
00312 RGN_Link_Pred_Succ_With_Prob( instru_pu_init_call_bb,goto_bb,1.0,
00313 regional_cfg );
00314 RGN_Link_Pred_Succ_With_Prob( goto_bb,target_bb,1.0 );
00315
00316 BB_freq( instru_init_call_bb ) = original_freq;
00317 BB_freq( instru_pu_init_call_bb ) = original_freq;
00318 BB_freq( goto_bb ) = original_freq;
00319
00320 }else
00321 {
00322 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
00323 float original_prob = Prob_Local(bb,target_bb);
00324 Unlink_Pred_Succ( bb,target_bb );
00325 Link_Pred_Succ( bb,instru_init_call_bb );
00326 Link_Pred_Succ( instru_init_call_bb,instru_pu_init_call_bb );
00327 Link_Pred_Succ( instru_pu_init_call_bb,goto_bb );
00328 Link_Pred_Succ( goto_bb,target_bb );
00329
00330 BB_freq( instru_init_call_bb ) = original_freq;
00331 BB_freq( instru_pu_init_call_bb ) = original_freq;
00332 BB_freq( goto_bb ) = original_freq;
00333 Set_Prob( bb,instru_init_call_bb,original_prob );
00334 Set_Prob( instru_init_call_bb,instru_pu_init_call_bb, 1.0 );
00335 Set_Prob( instru_pu_init_call_bb,goto_bb, 1.0 );
00336 Set_Prob( goto_bb,target_bb,1.0 );
00337 }
00338
00339 Change_Tgt_Label( op,tgt_label,instru_bb_label );
00340 }
00341 Prepare_Call_Init_Return_BB(BB_next(instru_pu_init_call_bb));
00342 }
00343 }else
00344 {
00345 BB* instru_init_call_bb = Gen_Call_BB( INSTR_INIT_NAME,
00346 outputfile_name,_phase,0 );
00347 Set_BB_profile_added(instru_init_call_bb);
00348 BB* instru_pu_init_call_bb = Gen_Call_BB( PU_INIT_NAME,
00349 _srcfile_pu_name, _instrument_count,0 );
00350 Set_BB_profile_added(instru_pu_init_call_bb);
00351 BB* target_bb = BBLIST_item( BB_succs( bb ) );
00352 Insert_BB( instru_init_call_bb,bb );
00353 Insert_BB( instru_pu_init_call_bb,instru_init_call_bb );
00354
00355 if (IPFEC_Enable_Region_Formation &&
00356 _phase != PROFILE_PHASE_BEFORE_REGION)
00357 {
00358 REGIONAL_CFG_NODE* node = Regional_Cfg_Node(bb);
00359 REGION* reg = node->Home_Region();
00360 REGIONAL_CFG* regional_cfg = reg->Regional_Cfg();
00361
00362 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
00363 float original_prob = Prob_Local(bb,target_bb);
00364 RGN_Gen_And_Insert_Node(instru_init_call_bb,bb,
00365 target_bb,regional_cfg);
00366 RGN_Gen_And_Insert_Node(instru_pu_init_call_bb,
00367 instru_init_call_bb,target_bb,regional_cfg);
00368
00369 RGN_Link_Pred_Succ_With_Prob( bb,instru_init_call_bb,
00370 original_prob,regional_cfg );
00371 RGN_Link_Pred_Succ_With_Prob( instru_init_call_bb,
00372 instru_pu_init_call_bb,1.0,regional_cfg);
00373 RGN_Link_Pred_Succ_With_Prob( instru_pu_init_call_bb,target_bb,
00374 1.0);
00375
00376 BB_freq( instru_init_call_bb ) = original_freq;
00377 BB_freq( instru_pu_init_call_bb ) = original_freq;
00378 }else
00379 {
00380 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
00381 float original_prob = Prob_Local(bb,target_bb);
00382 Unlink_Pred_Succ( bb,target_bb );
00383 Link_Pred_Succ( bb,instru_init_call_bb );
00384 Link_Pred_Succ( instru_init_call_bb,instru_pu_init_call_bb );
00385 Link_Pred_Succ( instru_pu_init_call_bb,target_bb );
00386 BB_freq( instru_init_call_bb ) = original_freq;
00387 BB_freq( instru_pu_init_call_bb ) = original_freq;
00388 Set_Prob( bb,instru_init_call_bb,original_prob );
00389 Set_Prob( instru_init_call_bb,instru_pu_init_call_bb, 1.0);
00390 Set_Prob( instru_pu_init_call_bb,target_bb,1.0 );
00391 }
00392 Prepare_Call_Init_Return_BB(BB_next(instru_pu_init_call_bb));
00393 }
00394 }else if ( bb != NULL && BB_call( bb ) )
00395 {
00396 BB* target_bb = BB_next( bb );
00397 if ( target_bb == NULL ) return;
00398
00399
00400
00401 BB* restore_bb = NULL;
00402 BB* instru_init_call_bb;
00403 int ret_reg_num = Get_Return_Reg_Sum( target_bb );
00404 int f_ret_reg_num = Get_Float_Return_Reg_Sum( target_bb );
00405 Is_True( ret_reg_num <= 0 || f_ret_reg_num <= 0 ,
00406 ( " return reg sum %d, float return reg sum %d" ,
00407 ret_reg_num, f_ret_reg_num ) );
00408 if ( ret_reg_num > 0 )
00409 {
00410 restore_bb = Gen_BB( );
00411 Set_BB_profile_added(restore_bb);
00412 instru_init_call_bb = Gen_Call_BB( INSTR_INIT_NAME,
00413 outputfile_name,_phase,1, ret_reg_num );
00414 Set_BB_profile_added(instru_init_call_bb);
00415 for ( int i = 0; i < ret_reg_num; i++ )
00416 {
00417 BB_Move_Op_To_Start( restore_bb,instru_init_call_bb,
00418 instru_init_call_bb->ops.last );
00419 }
00420 }else if ( f_ret_reg_num > 0 )
00421 {
00422 restore_bb = Gen_BB( );
00423 Set_BB_profile_added(restore_bb);
00424 instru_init_call_bb = Gen_Call_BB( INSTR_INIT_NAME,
00425 outputfile_name,_phase,2, f_ret_reg_num );
00426 Set_BB_profile_added(instru_init_call_bb);
00427 for ( int i = 0; i < f_ret_reg_num; i++ )
00428 {
00429 BB_Move_Op_To_Start( restore_bb,instru_init_call_bb,
00430 instru_init_call_bb->ops.last );
00431 }
00432 }else
00433 {
00434 instru_init_call_bb = Gen_Call_BB( INSTR_INIT_NAME,
00435 outputfile_name,_phase,0 );
00436 Set_BB_profile_added(instru_init_call_bb);
00437 }
00438
00439 BB* instru_pu_init_call_bb = Gen_Call_BB( PU_INIT_NAME,
00440 _srcfile_pu_name, _instrument_count,FALSE );
00441 Set_BB_profile_added(instru_pu_init_call_bb);
00442 Insert_BB( instru_init_call_bb,bb );
00443 Insert_BB( instru_pu_init_call_bb,instru_init_call_bb );
00444 if ( restore_bb != NULL )
00445 Insert_BB( restore_bb,instru_pu_init_call_bb );
00446
00447
00448 if (IPFEC_Enable_Region_Formation &&
00449 _phase != PROFILE_PHASE_BEFORE_REGION)
00450 {
00451 REGIONAL_CFG_NODE* node = Regional_Cfg_Node(bb);
00452 REGION* reg = node->Home_Region();
00453 REGIONAL_CFG* regional_cfg = reg->Regional_Cfg();
00454
00455 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
00456 float original_prob = Prob_Local(bb,target_bb);
00457 RGN_Gen_And_Insert_Node(instru_init_call_bb,bb,target_bb,regional_cfg);
00458 RGN_Gen_And_Insert_Node(instru_pu_init_call_bb,instru_init_call_bb,
00459 target_bb,regional_cfg);
00460 RGN_Unlink_Pred_Succ( bb,target_bb );
00461 RGN_Link_Pred_Succ_With_Prob( bb,instru_init_call_bb,
00462 original_prob,regional_cfg );
00463 RGN_Link_Pred_Succ_With_Prob( instru_init_call_bb,
00464 instru_pu_init_call_bb, 1.0 );
00465 BB_freq( instru_init_call_bb ) = original_freq;
00466 BB_freq( instru_pu_init_call_bb ) = original_freq;
00467
00468 if ( restore_bb != NULL )
00469 {
00470 RGN_Gen_And_Insert_Node(restore_bb,instru_pu_init_call_bb,
00471 target_bb,regional_cfg);
00472 RGN_Link_Pred_Succ_With_Prob( instru_pu_init_call_bb,restore_bb,
00473 1.0,regional_cfg );
00474 RGN_Link_Pred_Succ_With_Prob( restore_bb,target_bb,original_prob );
00475 BB_freq( restore_bb ) = original_freq;
00476 }else
00477 {
00478 RGN_Link_Pred_Succ_With_Prob( instru_pu_init_call_bb,target_bb,
00479 1.0 );
00480 }
00481 }else
00482 {
00483 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
00484 float original_prob = Prob_Local(bb,target_bb);
00485 Unlink_Pred_Succ( bb,target_bb );
00486 Link_Pred_Succ( bb,instru_init_call_bb );
00487 Link_Pred_Succ( instru_init_call_bb,instru_pu_init_call_bb );
00488
00489 BB_freq( instru_init_call_bb ) = original_freq;
00490 BB_freq( instru_pu_init_call_bb ) = original_freq;
00491 Set_Prob( bb,instru_init_call_bb,original_prob );
00492 Set_Prob( instru_init_call_bb,instru_pu_init_call_bb,1.0 );
00493
00494 if ( restore_bb != NULL )
00495 {
00496 Link_Pred_Succ( instru_pu_init_call_bb,restore_bb );
00497 Link_Pred_Succ( restore_bb,target_bb );
00498 BB_freq( restore_bb ) = original_freq;
00499 Set_Prob( instru_pu_init_call_bb,restore_bb,1.0 );
00500 Set_Prob( restore_bb,target_bb,1.0 );
00501 }else
00502 {
00503 Link_Pred_Succ( instru_pu_init_call_bb,target_bb );
00504 Set_Prob( instru_pu_init_call_bb,target_bb ,1.0);
00505 }
00506 }
00507 Prepare_Call_Init_Return_BB(BB_next(instru_pu_init_call_bb));
00508 }
00509 }
00510 }
00511
00512
00513
00514 void EDGE_PROFILE::CG_Annotate( )
00515 {
00516
00517
00518 if( Get_Trace( TP_A_PROF,TT_PROF_CFG ) )
00519 draw_global_cfg( "before edge profile annot" );
00520 INT32 _edge_instrument_count = 0;
00521
00522 for( BB* bb = _pu_last_bb; bb != NULL;
00523 bb = BB_prev( bb ) )
00524 {
00525 if(BB_Is_For_Instru(bb))
00526 {
00527 Set_BB_freq_fb_based(bb);
00528 CG_Annotate_Node( bb );
00529 }
00530 }
00531
00532 if( Get_Trace( TP_A_PROF,TT_PROF_CFG ) )
00533 draw_global_cfg( "before edge profile propagate" );
00534
00535 Propagate( );
00536 if( Get_Trace( TP_A_PROF,TT_PROF_CFG ) )
00537 draw_global_cfg( "before compute edge prob" );
00538
00539 Compute_Edge_Prob_Base_Freq( );
00540
00541 Check_CFG_Consistency( "edge profile annotation" );
00542 if( Get_Trace( TP_A_PROF,TT_PROF_CFG ) )
00543 draw_global_cfg( "after edge profile annot" );
00544 }
00545
00546
00547
00548
00549 void EDGE_PROFILE::CG_Instrument_Node( BB *bb )
00550 {
00551
00552 op* op = BB_xfer_op( bb );
00553 if ( op != NULL )
00554 {
00555 switch ( OP_code( op ) )
00556 {
00557
00558 case TOP_br_cond:
00559 case TOP_br_r_cond:
00560 case TOP_br:
00561 Instrument_Ip_Rel_Branch( bb );
00562 break;
00563
00564 case TOP_br_cloop:
00565 Instrument_Cloop_Branch( bb );
00566 break;
00567
00568 case TOP_br_ctop:
00569 case TOP_br_wtop:
00570 Instrument_Top_Branch( bb );
00571 break;
00572
00573 case TOP_brp_r:
00574 case TOP_br_r:
00575 Instrument_Indirect_Cond_Branch( bb );
00576 break;
00577
00578 default:
00579 Instrument_None_and_Other_Xfer( bb );
00580 break;
00581 }
00582 }else
00583 Instrument_None_and_Other_Xfer( bb );
00584 }
00585
00586
00587
00588
00589 void EDGE_PROFILE::CG_Annotate_Node( BB *bb )
00590 {
00591 op* op = BB_xfer_op( bb );
00592 if ( op != NULL )
00593 {
00594 switch ( OP_code( op ) )
00595 {
00596
00597 case TOP_br_cond:
00598 case TOP_br_r_cond:
00599 case TOP_br:
00600 Annotate_Ip_Rel_Branch( bb );
00601 break;
00602
00603 case TOP_br_cloop:
00604 Annotate_Cloop_Branch( bb );
00605 break;
00606
00607 case TOP_br_ctop:
00608 case TOP_br_wtop:
00609 Annotate_Top_Branch( bb );
00610 break;
00611
00612 case TOP_brp_r:
00613 case TOP_br_r:
00614 Annotate_Indirect_Cond_Branch( bb );
00615 break;
00616
00617 default:
00618 Annotate_None_and_Other_Xfer( bb );
00619 break;
00620 }
00621 }else
00622 Annotate_None_and_Other_Xfer( bb );
00623 }
00624
00625 void EDGE_PROFILE::Instrument_Indirect_Cond_Branch( BB* bb )
00626 {
00627 BBLIST* edge = BB_succs( bb );
00628 INT32 bblist_len =BBlist_Len( edge );
00629 OP* op = BB_xfer_op( bb );
00630 while ( edge != NULL && bblist_len-- )
00631 {
00632 BBLIST* nedge = edge;
00633 edge = BBLIST_next( edge );
00634
00635 BB* target_bb = BBLIST_item( nedge );
00636 if ( BB_profile_added(target_bb) )
00637 continue;
00638
00639 INT32 id = _instrument_count++;
00640 ++_count_indirect_cond_branch;
00641
00642 BB* instru_bb = Gen_Instru_Call_BB( EDGE_INST_NAME,_srcfile_pu_name,id );
00643 Set_BB_profile_added(instru_bb);
00644
00645
00646 LABEL_IDX instru_bb_label = Gen_Label_For_BB( instru_bb );
00647 LABEL_IDX tgt_label;
00648 if ( Get_Br_Op_Tgt_Label( op ) != LABEL_IDX_NONE &&
00649 Get_Label_BB( Get_Br_Op_Tgt_Label( op ) ) == target_bb )
00650 tgt_label = Get_Br_Op_Tgt_Label( op );
00651 else
00652 tgt_label = Gen_Label_For_BB( target_bb );
00653
00654 Change_BB_Label( instru_bb,tgt_label );
00655 Change_BB_Label( target_bb,instru_bb_label );
00656
00657 if( BB_next( bb ) == target_bb )
00658 {
00659 Insert_BB( instru_bb,bb );
00660
00661
00662 if (IPFEC_Enable_Region_Formation &&
00663 _phase != PROFILE_PHASE_BEFORE_REGION)
00664 {
00665 REGIONAL_CFG_NODE* node = Regional_Cfg_Node(bb);
00666 REGION* reg = node->Home_Region();
00667 REGIONAL_CFG* regional_cfg = reg->Regional_Cfg();
00668
00669 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
00670 float original_prob = Prob_Local(bb,target_bb);
00671
00672 RGN_Gen_And_Insert_Node(instru_bb,bb,target_bb,regional_cfg);
00673 RGN_Unlink_Pred_Succ( bb,target_bb );
00674 RGN_Link_Pred_Succ_With_Prob( bb,instru_bb,original_prob,regional_cfg );
00675 RGN_Link_Pred_Succ_With_Prob( instru_bb,target_bb,original_prob );
00676 BB_freq( instru_bb ) = original_freq;
00677
00678 }else
00679 {
00680 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
00681 float original_prob = Prob_Local(bb,target_bb);
00682 Unlink_Pred_Succ( bb,target_bb );
00683 Link_Pred_Succ( bb,instru_bb );
00684 Link_Pred_Succ( instru_bb,target_bb );
00685 BB_freq( instru_bb ) = original_freq;
00686 Set_Prob( bb,instru_bb,original_prob );
00687 Set_Prob( instru_bb,target_bb,1.0 );
00688 }
00689 }else
00690 {
00691 BB* goto_bb = Gen_BB( );
00692 Set_BB_profile_added(goto_bb);
00693 BB* old_last_bb = _pu_last_bb;
00694 _pu_last_bb = goto_bb;
00695 Insert_BB( instru_bb,old_last_bb );
00696 Insert_BB( goto_bb,instru_bb );
00697 Add_Goto( goto_bb, target_bb );
00698
00699
00700 if (IPFEC_Enable_Region_Formation &&
00701 _phase != PROFILE_PHASE_BEFORE_REGION)
00702 {
00703 REGIONAL_CFG_NODE* node = Regional_Cfg_Node(bb);
00704 REGION* reg = node->Home_Region();
00705 REGIONAL_CFG* regional_cfg = reg->Regional_Cfg();
00706
00707 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
00708 float original_prob = Prob_Local(bb,target_bb);
00709
00710 RGN_Gen_And_Insert_Node(instru_bb,bb,target_bb,regional_cfg);
00711 RGN_Gen_And_Insert_Node(goto_bb,bb,instru_bb,regional_cfg);
00712 RGN_Unlink_Pred_Succ( bb,target_bb );
00713 RGN_Link_Pred_Succ_With_Prob( bb,instru_bb,original_prob,regional_cfg );
00714 RGN_Link_Pred_Succ_With_Prob( instru_bb,goto_bb,original_prob,regional_cfg );
00715 RGN_Link_Pred_Succ_With_Prob( goto_bb,target_bb,original_prob );
00716 BB_freq( instru_bb ) = original_freq;
00717 BB_freq( goto_bb ) = original_freq;
00718 }else
00719 {
00720 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
00721 float original_prob = Prob_Local(bb,target_bb);
00722 Unlink_Pred_Succ( bb,target_bb );
00723 Link_Pred_Succ( bb,instru_bb );
00724 Link_Pred_Succ( instru_bb,goto_bb );
00725 Link_Pred_Succ( goto_bb,target_bb );
00726 BB_freq( instru_bb ) = original_freq;
00727 BB_freq( goto_bb ) = original_freq;
00728 Set_Prob( bb,instru_bb,original_prob );
00729 Set_Prob( instru_bb,goto_bb,1.0 );
00730 Set_Prob( goto_bb,target_bb,1.0 );
00731 }
00732
00733 OP *branch_op = BB_branch_op( bb );
00734 Change_Tgt_Label( branch_op,tgt_label,instru_bb_label );
00735 }
00736 }
00737 }
00738
00739 void EDGE_PROFILE::Instrument_Ip_Rel_Branch( BB *bb )
00740 {
00741 BBLIST* edge = BB_succs( bb );
00742 INT32 bblist_len =BBlist_Len( edge );
00743 OP* op = BB_xfer_op( bb );
00744 while ( edge != NULL && bblist_len-- )
00745 {
00746 BBLIST* nedge = edge;
00747 edge = BBLIST_next( edge );
00748 BB* target_bb = BBLIST_item( nedge );
00749 if ( BB_profile_added(target_bb) )
00750 continue;
00751 LABEL_IDX tgt_label;
00752 if ( Get_Label_BB( Get_Br_Op_Tgt_Label( op ) ) == target_bb )
00753 tgt_label = Get_Br_Op_Tgt_Label( op );
00754 else
00755 tgt_label = Gen_Label_For_BB( target_bb );
00756
00757 if( BB_next( bb ) == target_bb )
00758 {
00759 INT32 id = _instrument_count++;
00760 BB* instru_bb = Gen_Instru_Call_BB( EDGE_INST_NAME,
00761 _srcfile_pu_name,id );
00762 Set_BB_profile_added(instru_bb);
00763
00764 LABEL_IDX instru_bb_label = Gen_Label_For_BB( instru_bb );
00765 Insert_BB( instru_bb,bb );
00766
00767
00768 if (IPFEC_Enable_Region_Formation &&
00769 _phase != PROFILE_PHASE_BEFORE_REGION)
00770 {
00771 REGIONAL_CFG_NODE* node = Regional_Cfg_Node( target_bb );
00772 REGION* reg = node->Home_Region();
00773 REGIONAL_CFG* regional_cfg = reg->Regional_Cfg();
00774
00775 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
00776 float original_prob = Prob_Local(bb,target_bb);
00777 RGN_Gen_And_Insert_Node(instru_bb,bb,target_bb,regional_cfg);
00778 RGN_Unlink_Pred_Succ( bb,target_bb );
00779 RGN_Link_Pred_Succ_With_Prob( bb,instru_bb,original_prob,regional_cfg );
00780 RGN_Link_Pred_Succ_With_Prob( instru_bb,target_bb,1.0 );
00781 BB_freq( instru_bb ) = original_freq;
00782 }else
00783 {
00784 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
00785 float original_prob = Prob_Local(bb,target_bb);
00786 Unlink_Pred_Succ( bb,target_bb );
00787 Link_Pred_Succ( bb,instru_bb );
00788 Link_Pred_Succ( instru_bb,target_bb );
00789 BB_freq( instru_bb ) = original_freq;
00790 Set_Prob( bb,instru_bb,original_prob );
00791 Set_Prob( instru_bb,target_bb,1.0 );
00792 }
00793
00794 OP *branch_op = BB_branch_op( bb );
00795 if ( tgt_label == Get_Op_Label( branch_op ) )
00796 Change_Tgt_Label( branch_op,tgt_label,instru_bb_label );
00797 }else
00798 {
00799 INT32 id = _instrument_count++;
00800 BB* instru_bb = Gen_Instru_Call_BB( EDGE_INST_NAME,
00801 _srcfile_pu_name,id );
00802 Set_BB_profile_added(instru_bb);
00803
00804 LABEL_IDX instru_bb_label = Gen_Label_For_BB( instru_bb );
00805
00806 BB* goto_bb = Gen_BB( );
00807 Set_BB_profile_added(goto_bb);
00808 BB* old_last_bb = _pu_last_bb;
00809 _pu_last_bb = goto_bb;
00810 Insert_BB( instru_bb,old_last_bb );
00811 Insert_BB( goto_bb,instru_bb );
00812 Add_Goto( goto_bb, target_bb );
00813
00814
00815 if (IPFEC_Enable_Region_Formation &&
00816 _phase != PROFILE_PHASE_BEFORE_REGION)
00817 {
00818 REGIONAL_CFG_NODE* node = Regional_Cfg_Node(bb);
00819 REGION* reg = node->Home_Region();
00820 REGIONAL_CFG* regional_cfg = reg->Regional_Cfg();
00821
00822 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
00823 float original_prob = Prob_Local(bb,target_bb);
00824
00825 RGN_Gen_And_Insert_Node(instru_bb,bb,target_bb,regional_cfg);
00826 RGN_Gen_And_Insert_Node(goto_bb,instru_bb,target_bb,regional_cfg);
00827 RGN_Unlink_Pred_Succ( bb,target_bb );
00828 RGN_Link_Pred_Succ_With_Prob( bb,instru_bb,original_prob,regional_cfg );
00829 RGN_Link_Pred_Succ_With_Prob( instru_bb,goto_bb,1.0,regional_cfg );
00830 RGN_Link_Pred_Succ_With_Prob( goto_bb,target_bb,1.0 );
00831 BB_freq( instru_bb ) = original_freq;
00832 BB_freq( goto_bb ) = original_freq;
00833 }else
00834 {
00835 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
00836 float original_prob = Prob_Local(bb,target_bb);
00837 Unlink_Pred_Succ( bb,target_bb );
00838 Link_Pred_Succ( bb,instru_bb );
00839 Link_Pred_Succ( instru_bb,goto_bb );
00840 Link_Pred_Succ( goto_bb,target_bb );
00841 BB_freq( instru_bb ) = original_freq;
00842 BB_freq( goto_bb ) = original_freq;
00843 Set_Prob( bb,instru_bb,original_prob );
00844 Set_Prob( instru_bb,goto_bb,1.0 );
00845 Set_Prob( goto_bb,target_bb,1.0 );
00846 }
00847
00848 OP *branch_op = BB_branch_op( bb );
00849 if ( tgt_label == Get_Op_Label( branch_op ) )
00850 Change_Tgt_Label( branch_op,tgt_label,instru_bb_label );
00851 }
00852 }
00853 }
00854
00855 void EDGE_PROFILE::Instrument_Cloop_Branch( BB *bb )
00856 {
00857 BBLIST* edge = BB_succs( bb );
00858 INT32 bblist_len =BBlist_Len( edge );
00859 OP* op = BB_xfer_op( bb );
00860 while ( edge != NULL && bblist_len-- )
00861 {
00862 BBLIST* nedge = edge;
00863 edge = BBLIST_next( edge );
00864
00865 BB* target_bb = BBLIST_item( nedge );
00866
00867 if ( BB_profile_added(target_bb) )
00868 continue;
00869
00870 INT32 id = _instrument_count++;
00871 ++_count_cloop;
00872
00873 BB* instru_bb = Gen_Instru_Call_BB( EDGE_INST_NAME,_srcfile_pu_name,id );
00874 Set_BB_profile_added(instru_bb);
00875
00876 LABEL_IDX instru_bb_label = Gen_Label_For_BB( instru_bb );
00877
00878 LABEL_IDX tgt_label;
00879
00880 if( Get_Label_BB( Get_Br_Op_Tgt_Label( op ) ) == target_bb )
00881 tgt_label = Get_Br_Op_Tgt_Label( op );
00882 else
00883 tgt_label = Gen_Label_For_BB( target_bb );
00884
00885
00886 if( BB_next( bb ) == target_bb )
00887 {
00888 Insert_BB( instru_bb,bb );
00889
00890 if (IPFEC_Enable_Region_Formation &&
00891 _phase != PROFILE_PHASE_BEFORE_REGION)
00892 {
00893 REGIONAL_CFG_NODE* node = Regional_Cfg_Node(bb);
00894 REGION* reg = node->Home_Region();
00895 REGIONAL_CFG* regional_cfg = reg->Regional_Cfg();
00896
00897 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
00898 float original_prob = Prob_Local(bb,target_bb);
00899 RGN_Gen_And_Insert_Node(instru_bb,bb,target_bb,regional_cfg);
00900 RGN_Unlink_Pred_Succ( bb,target_bb );
00901 RGN_Link_Pred_Succ_With_Prob( bb,instru_bb,original_prob,regional_cfg );
00902 RGN_Link_Pred_Succ_With_Prob( instru_bb,target_bb,1.0 );
00903 BB_freq( instru_bb ) = original_freq;
00904 }else
00905 {
00906 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
00907 float original_prob = Prob_Local(bb,target_bb);
00908 Unlink_Pred_Succ( bb,target_bb );
00909 Link_Pred_Succ( bb,instru_bb );
00910 Link_Pred_Succ( instru_bb,target_bb );
00911 BB_freq( instru_bb ) = original_freq;
00912 Set_Prob( bb,instru_bb,original_prob );
00913 Set_Prob( instru_bb,target_bb,1.0 );
00914 }
00915 }else
00916 {
00917 BB* goto_bb = Gen_BB( );
00918 Set_BB_profile_added(goto_bb);
00919 BB* old_last_bb = _pu_last_bb;
00920 _pu_last_bb = goto_bb;
00921 Insert_BB( instru_bb,old_last_bb );
00922 Insert_BB( goto_bb,instru_bb );
00923 Add_Goto( goto_bb, target_bb );
00924
00925
00926 if (IPFEC_Enable_Region_Formation &&
00927 _phase != PROFILE_PHASE_BEFORE_REGION)
00928 {
00929 REGIONAL_CFG_NODE* node = Regional_Cfg_Node(bb);
00930 REGION* reg = node->Home_Region();
00931 REGIONAL_CFG* regional_cfg = reg->Regional_Cfg();
00932
00933 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
00934 float original_prob = Prob_Local(bb,target_bb);
00935
00936 RGN_Gen_And_Insert_Node(instru_bb,bb,target_bb,regional_cfg);
00937 RGN_Gen_And_Insert_Node(goto_bb,bb,instru_bb,regional_cfg);
00938 RGN_Unlink_Pred_Succ( bb,target_bb );
00939 RGN_Link_Pred_Succ_With_Prob( bb,instru_bb,original_prob,regional_cfg );
00940 RGN_Link_Pred_Succ_With_Prob( instru_bb,goto_bb,1.0,regional_cfg );
00941 RGN_Link_Pred_Succ_With_Prob( goto_bb,target_bb,1.0 );
00942 BB_freq( instru_bb ) = original_freq;
00943 BB_freq( goto_bb ) = original_freq;
00944 }else
00945 {
00946 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
00947 float original_prob = Prob_Local(bb,target_bb);
00948 Unlink_Pred_Succ( bb,target_bb );
00949 Link_Pred_Succ( bb,instru_bb );
00950 Link_Pred_Succ( instru_bb,goto_bb );
00951 Link_Pred_Succ( goto_bb,target_bb );
00952 BB_freq( instru_bb ) = original_freq;
00953 BB_freq( goto_bb ) = original_freq;
00954 Set_Prob( bb,instru_bb,original_prob );
00955 Set_Prob( instru_bb,goto_bb,1.0 );
00956 Set_Prob( goto_bb,target_bb,1.0 );
00957 }
00958 }
00959
00960
00961 OP *branch_op = BB_branch_op( bb );
00962 Change_Tgt_Label( branch_op,tgt_label,instru_bb_label );
00963 }
00964 }
00965
00966 void EDGE_PROFILE::Instrument_Top_Branch( BB *bb )
00967 {
00968 BBLIST* edge = BB_succs( bb );
00969 INT32 bblist_len =BBlist_Len( edge );
00970 OP* op = BB_xfer_op( bb );
00971 while ( edge != NULL && bblist_len-- )
00972 {
00973 BBLIST* nedge = edge;
00974 edge = BBLIST_next( edge );
00975
00976
00977 BB* target_bb = BBLIST_item( nedge );
00978
00979 if ( BB_profile_added(target_bb) )
00980 continue;
00981
00982 INT32 id = _instrument_count++;
00983 ++_count_top;
00984
00985 BB* instru_bb = Gen_Instru_Call_BB( EDGE_INST_NAME,_srcfile_pu_name,id );
00986 Set_BB_profile_added(instru_bb);
00987
00988 LABEL_IDX instru_bb_label = Gen_Label_For_BB( instru_bb );
00989 LABEL_IDX tgt_label;
00990 if ( Get_Label_BB( Get_Br_Op_Tgt_Label( op ) ) == target_bb )
00991 tgt_label = Get_Br_Op_Tgt_Label( op );
00992 else
00993 tgt_label = Gen_Label_For_BB( target_bb );
00994
00995
00996 if( BB_next( bb ) == target_bb )
00997 {
00998 Insert_BB( instru_bb,bb );
00999
01000 if (IPFEC_Enable_Region_Formation &&
01001 _phase != PROFILE_PHASE_BEFORE_REGION)
01002 {
01003 REGIONAL_CFG_NODE* node = Regional_Cfg_Node(bb);
01004 REGION* reg = node->Home_Region();
01005 REGIONAL_CFG* regional_cfg = reg->Regional_Cfg();
01006
01007 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
01008 float original_prob = Prob_Local(bb,target_bb);
01009 RGN_Gen_And_Insert_Node(instru_bb,bb,target_bb,regional_cfg);
01010 RGN_Unlink_Pred_Succ( bb,target_bb );
01011 RGN_Link_Pred_Succ_With_Prob( bb,instru_bb,original_prob,regional_cfg );
01012 RGN_Link_Pred_Succ_With_Prob( instru_bb,target_bb,original_prob );
01013 BB_freq( instru_bb ) = original_freq;
01014 }else
01015 {
01016 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
01017 float original_prob = Prob_Local(bb,target_bb);
01018 Unlink_Pred_Succ( bb,target_bb );
01019 Link_Pred_Succ( bb,instru_bb );
01020 Link_Pred_Succ( instru_bb,target_bb );
01021 BB_freq( instru_bb ) = original_freq;
01022 Set_Prob( bb,instru_bb,original_prob );
01023 Set_Prob( instru_bb,target_bb,1.0 );
01024 }
01025 }else
01026 {
01027 BB* goto_bb = Gen_BB( );
01028 Set_BB_profile_added(goto_bb);
01029 BB* old_last_bb = _pu_last_bb;
01030 _pu_last_bb = goto_bb;
01031 Insert_BB( instru_bb,old_last_bb );
01032 Insert_BB( goto_bb,instru_bb );
01033 Add_Goto( goto_bb, target_bb );
01034
01035
01036 if (IPFEC_Enable_Region_Formation &&
01037 _phase != PROFILE_PHASE_BEFORE_REGION)
01038 {
01039 REGIONAL_CFG_NODE* node = Regional_Cfg_Node(bb);
01040 REGION* reg = node->Home_Region();
01041 REGIONAL_CFG* regional_cfg = reg->Regional_Cfg();
01042
01043 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
01044 float original_prob = Prob_Local(bb,target_bb);
01045
01046 RGN_Gen_And_Insert_Node(instru_bb,bb,target_bb,regional_cfg);
01047 RGN_Gen_And_Insert_Node(goto_bb,bb,instru_bb,regional_cfg);
01048 RGN_Unlink_Pred_Succ( bb,target_bb );
01049 RGN_Link_Pred_Succ_With_Prob( bb,instru_bb,original_prob,regional_cfg );
01050 RGN_Link_Pred_Succ_With_Prob( instru_bb,goto_bb,original_prob,regional_cfg );
01051 RGN_Link_Pred_Succ_With_Prob( goto_bb,target_bb,original_prob );
01052 BB_freq( instru_bb ) = original_freq;
01053 BB_freq( goto_bb ) = original_freq;
01054 }else
01055 {
01056 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
01057 float original_prob = Prob_Local(bb,target_bb);
01058 Unlink_Pred_Succ( bb,target_bb );
01059 Link_Pred_Succ( bb,instru_bb );
01060 Link_Pred_Succ( instru_bb,goto_bb );
01061 Link_Pred_Succ( goto_bb,target_bb );
01062 BB_freq( instru_bb ) = original_freq;
01063 BB_freq( goto_bb ) = original_freq;
01064 Set_Prob( bb,instru_bb,original_prob );
01065 Set_Prob( instru_bb,goto_bb,1.0 );
01066 Set_Prob( goto_bb,target_bb,1.0 );
01067 }
01068 }
01069
01070
01071 OP *branch_op = BB_branch_op( bb );
01072 Change_Tgt_Label( branch_op,tgt_label,instru_bb_label );
01073 }
01074 }
01075
01076 void EDGE_PROFILE::Instrument_None_and_Other_Xfer( BB *bb )
01077 {
01078
01079 Is_True( bb!=NULL,( "can not instrument after a NULL BB" ) );
01080 if( BB_succs_len( bb ) > 1 )
01081 {
01082 DevWarn( "BB %d does not have only succeed BB!",BB_id( bb ) );
01083 return;
01084 }
01085 if( BB_succs_len( bb ) == 0 )
01086 return;
01087 if ( BBLIST_item( BB_succs( bb ) ) != BB_next( bb ) )
01088 {
01089 DevWarn( "the next BB of BB %d is not succeed BB!",BB_id( bb ) );
01090 return;
01091 }
01092
01093 if ( BB_profile_added(BB_next( bb )) )
01094 return;
01095 OP* branch_op = BB_xfer_op( bb );
01096 INT32 id = _instrument_count++;
01097
01098 if ( BB_call( bb ) )
01099 {
01100 BB* bp;
01101 BB* target_bb = BB_next( bb );
01102
01103
01104 BB* restore_bb = NULL;
01105 int ret_reg_num = Get_Return_Reg_Sum( target_bb );
01106 int f_ret_reg_num = Get_Float_Return_Reg_Sum( target_bb );
01107 Is_True( ret_reg_num <= 0 || f_ret_reg_num <= 0 ,
01108 ( " return reg sum %d, float return reg sum %d" ,
01109 ret_reg_num, f_ret_reg_num ) );
01110 if ( ret_reg_num > 0 )
01111 {
01112 restore_bb = Gen_BB( );
01113 Set_BB_profile_added(restore_bb);
01114 bp = Gen_Call_BB( EDGE_INST_NAME,_pu_hdr_return_tn, id, 1, ret_reg_num );
01115 Set_BB_profile_added(bp);
01116 for ( int i = 0; i < ret_reg_num; i++ )
01117 {
01118 BB_Move_Op_To_Start( restore_bb,bp,
01119 bp->ops.last );
01120 }
01121 }else if ( f_ret_reg_num > 0 )
01122 {
01123 restore_bb = Gen_BB( );
01124 Set_BB_profile_added(restore_bb);
01125 bp = Gen_Call_BB( EDGE_INST_NAME,_pu_hdr_return_tn,
01126 id, 2, f_ret_reg_num );
01127 Set_BB_profile_added(bp);
01128 for ( int i = 0; i < f_ret_reg_num; i++ )
01129 {
01130 BB_Move_Op_To_Start( restore_bb,bp,
01131 bp->ops.last );
01132 }
01133 }else
01134 {
01135 bp = Gen_Call_BB( EDGE_INST_NAME,_pu_hdr_return_tn, id, 0);
01136 Set_BB_profile_added(bp);
01137 }
01138
01139
01140 Insert_BB( bp,bb );
01141 if ( restore_bb != NULL )
01142 Insert_BB( restore_bb,bp );
01143
01144 if (IPFEC_Enable_Region_Formation &&
01145 _phase != PROFILE_PHASE_BEFORE_REGION)
01146 {
01147 REGIONAL_CFG_NODE* node = Regional_Cfg_Node(bb);
01148 REGION* reg = node->Home_Region();
01149 REGIONAL_CFG* regional_cfg = reg->Regional_Cfg();
01150
01151 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
01152 float original_prob = Prob_Local(bb,target_bb);
01153 RGN_Gen_And_Insert_Node(bp,bb,target_bb,regional_cfg);
01154 RGN_Unlink_Pred_Succ( bb,target_bb );
01155 RGN_Link_Pred_Succ_With_Prob( bb,bp,1.0,regional_cfg );
01156 BB_freq( bp ) = original_freq;
01157 if ( restore_bb != NULL )
01158 {
01159 RGN_Gen_And_Insert_Node(restore_bb,bb,bp,regional_cfg);
01160 RGN_Link_Pred_Succ_With_Prob( bp,restore_bb,1.0,regional_cfg );
01161 RGN_Link_Pred_Succ_With_Prob( restore_bb,target_bb,1.0 );
01162 BB_freq( restore_bb ) = original_freq;
01163 }else
01164 {
01165 RGN_Link_Pred_Succ_With_Prob( bp,target_bb,1.0 );
01166 }
01167 }else
01168 {
01169 float original_freq = Prob_Local(bb,target_bb) * BB_freq(bb);
01170 float original_prob = Prob_Local(bb,target_bb);
01171 Unlink_Pred_Succ( bb,target_bb );
01172 Link_Pred_Succ( bb,bp );
01173 BB_freq( bp ) = original_freq;
01174 Set_Prob( bb,bp,original_prob );
01175 if ( restore_bb != NULL )
01176 {
01177 Link_Pred_Succ( bp,restore_bb );
01178 Link_Pred_Succ( restore_bb,target_bb );
01179 BB_freq( restore_bb ) = original_freq;
01180 Set_Prob( bp,restore_bb,1.0 );
01181 Set_Prob( restore_bb,target_bb,1.0 );
01182 }else
01183 {
01184 Link_Pred_Succ( bp,target_bb);
01185 Set_Prob( bp,target_bb,1.0 );
01186 }
01187 }
01188 }else
01189 {
01190 BB* bp = Gen_Call_BB( EDGE_INST_NAME,_pu_hdr_return_tn, id,0 );
01191 Set_BB_profile_added(bp);
01192 Insert_BB( bp,bb );
01193 BB* succ = BBLIST_item( BB_succs( bb ) );
01194
01195
01196 if (IPFEC_Enable_Region_Formation &&
01197 _phase != PROFILE_PHASE_BEFORE_REGION)
01198 {
01199 REGIONAL_CFG_NODE* node = Regional_Cfg_Node(bb);
01200 REGION* reg = node->Home_Region();
01201 REGIONAL_CFG* regional_cfg = reg->Regional_Cfg();
01202
01203 float original_freq = Prob_Local(bb,succ) * BB_freq(bb);
01204 float original_prob = Prob_Local(bb,succ);
01205 RGN_Gen_And_Insert_Node(bp,bb,succ,regional_cfg);
01206 RGN_Unlink_Pred_Succ( bb,succ );
01207 RGN_Link_Pred_Succ_With_Prob( bb,bp,1.0,regional_cfg );
01208 RGN_Link_Pred_Succ_With_Prob( bp,succ,1.0);
01209 BB_freq( bp ) = original_freq;
01210
01211 }else
01212 {
01213 float original_freq = Prob_Local(bb,succ) * BB_freq(bb);
01214 float original_prob = Prob_Local(bb,succ);
01215 Unlink_Pred_Succ( bb,succ );
01216 Link_Pred_Succ( bp,succ );
01217 Link_Pred_Succ( bb,bp );
01218 BB_freq( bp ) = original_freq;
01219 Set_Prob( bp,succ,1.0 );
01220 Set_Prob( bb,bp,original_prob );
01221 }
01222 }
01223 }
01224
01225
01226
01227
01228
01229 void EDGE_PROFILE::Change_Tgt_Label( op* branch_op,
01230 LABEL_IDX old_label,LABEL_IDX new_label )
01231 {
01232
01233 INT tn_num = OP_opnds( branch_op );
01234 for( int i = 0; i<tn_num; i++ )
01235 {
01236 TN* tgt_tn = OP_opnd( branch_op, i );
01237 if( TN_is_label( tgt_tn ) && ( TN_label( tgt_tn ) == old_label ) )
01238 {
01239 Set_TN_label( tgt_tn, new_label );
01240 break;
01241 }
01242 }
01243 }
01244
01245 void EDGE_PROFILE::Annotate_Indirect_Cond_Branch( BB *bb )
01246 {
01247 for( BBLIST* edge = BB_succs( bb ); edge != NULL;
01248 edge = BBLIST_next( edge ) )
01249 {
01250 INT32 id = _instrument_count++;
01251
01252 PU_PROFILE_HANDLES& handles = _fb_handles;
01253 FB_Info_Edge info_branch( FB_FREQ_ZERO );
01254 for ( PU_PROFILE_ITERATOR i( handles.begin( ) ); i != handles.end( );
01255 ++i )
01256 {
01257 FB_Info_Edge& info = Get_Edge_Profile ( *i, id );
01258 if ( &info != NULL )
01259 info_branch.freq_edge += info.freq_edge;
01260 }
01261
01262 BBLIST_freq( edge ) = info_branch.freq_edge.Value( );
01263
01264 if( Get_Trace( TP_A_PROF,TT_PROF_FEEDBACK_DUMP ) )
01265 Dump_Edge_Info(bb,edge);
01266 }
01267 }
01268
01269 void EDGE_PROFILE::Annotate_Ip_Rel_Branch( BB *bb )
01270 {
01271 for( BBLIST* edge = BB_succs( bb ); edge != NULL;
01272 edge = BBLIST_next( edge ) )
01273 {
01274 BB* target_bb = BBLIST_item( edge );
01275 {
01276 INT32 id = _instrument_count++;
01277
01278 PU_PROFILE_HANDLES& handles = FB_Handle( );
01279 FB_Info_Edge info_Ip_Rel( FB_FREQ_ZERO );
01280 for ( PU_PROFILE_ITERATOR i( handles.begin( ) ); i != handles.end( );
01281 ++i )
01282 {
01283 FB_Info_Edge& info = Get_Edge_Profile ( *i, id );
01284 if ( &info != NULL )
01285 info_Ip_Rel.freq_edge += info.freq_edge;
01286 }
01287
01288 BBLIST_freq( edge ) = info_Ip_Rel.freq_edge.Value( );
01289 if( Get_Trace( TP_A_PROF,TT_PROF_FEEDBACK_DUMP ) )
01290 Dump_Edge_Info(bb,edge);
01291 }
01292 }
01293 }
01294
01295 void EDGE_PROFILE::Annotate_Cloop_Branch( BB *bb )
01296 {
01297 for( BBLIST* edge = BB_succs( bb ); edge != NULL;
01298 edge = BBLIST_next( edge ) )
01299 {
01300 INT32 id = _instrument_count++;
01301
01302 PU_PROFILE_HANDLES& handles = FB_Handle( );
01303 FB_Info_Edge info_loop( FB_FREQ_ZERO );
01304 for ( PU_PROFILE_ITERATOR i( handles.begin( ) ); i != handles.end( );
01305 ++i )
01306 {
01307 FB_Info_Edge& info = Get_Edge_Profile ( *i, id );
01308 if ( &info != NULL )
01309 info_loop.freq_edge += info.freq_edge;
01310 }
01311
01312 BBLIST_freq( edge ) = info_loop.freq_edge.Value( );
01313 if( Get_Trace( TP_A_PROF,TT_PROF_FEEDBACK_DUMP ) )
01314 Dump_Edge_Info(bb,edge);
01315 }
01316 }
01317
01318 void EDGE_PROFILE::Annotate_Top_Branch( BB *bb )
01319 {
01320 for( BBLIST* edge = BB_succs( bb ); edge != NULL;
01321 edge = BBLIST_next( edge ) )
01322 {
01323 INT32 id = _instrument_count++;
01324 ++_count_top;
01325
01326 PU_PROFILE_HANDLES& handles = FB_Handle( );
01327 FB_Info_Edge info_top( FB_FREQ_ZERO );
01328 for ( PU_PROFILE_ITERATOR i( handles.begin( ) ); i != handles.end( );
01329 ++i )
01330 {
01331 FB_Info_Edge& info = Get_Edge_Profile ( *i, id );
01332 if ( &info != NULL )
01333 info_top.freq_edge += info.freq_edge;
01334 }
01335
01336 BBLIST_freq( edge ) = info_top.freq_edge.Value( );
01337 if( Get_Trace( TP_A_PROF,TT_PROF_FEEDBACK_DUMP ) )
01338 Dump_Edge_Info(bb,edge);
01339 }
01340 }
01341
01342 void EDGE_PROFILE::Annotate_Call_Branch( BB *bb )
01343 {
01344 INT32 id = _instrument_count++;
01345 ++_count_call;
01346
01347 id = _instrument_count++;
01348 ++_count_call;
01349
01350 PU_PROFILE_HANDLES& handles = FB_Handle( );
01351 FB_Info_Edge info_call( FB_FREQ_ZERO );
01352 for ( PU_PROFILE_ITERATOR i( handles.begin( ) );
01353 i != handles.end ( ); ++i )
01354 {
01355 FB_Info_Edge& info = Get_Edge_Profile( *i, id );
01356 if ( &info != NULL )
01357 info_call.freq_edge += info.freq_edge;
01358 }
01359
01360 BBLIST* edge = BB_succs( bb );
01361 if( edge != NULL )
01362 BBLIST_freq( edge ) = info_call.freq_edge.Value( );
01363 if( Get_Trace( TP_A_PROF,TT_PROF_FEEDBACK_DUMP ) )
01364 Dump_Edge_Info(bb,edge);
01365 }
01366
01367 void EDGE_PROFILE::Annotate_None_and_Other_Xfer( BB *bb )
01368 {
01369 Is_True( bb!=NULL,( "can not annotate after a NULL BB" ) );
01370 if( BB_succs_len( bb ) > 1 )
01371 {
01372 DevWarn( "BB %d does not have only succeed BB!",BB_id( bb ) );
01373 return;
01374 }
01375 if( BB_succs( bb ) == NULL )
01376 return;
01377
01378 OP* branch_op = BB_xfer_op( bb );
01379 INT32 id = _instrument_count++;
01380
01381 PU_PROFILE_HANDLES& handles = FB_Handle( );
01382 FB_Info_Edge info_top( FB_FREQ_ZERO );
01383 for ( PU_PROFILE_ITERATOR i( handles.begin( ) ); i != handles.end( );
01384 ++i )
01385 {
01386 FB_Info_Edge& info = Get_Edge_Profile ( *i, id );
01387 if ( &info != NULL )
01388 info_top.freq_edge += info.freq_edge;
01389 }
01390
01391 BBLIST* edge = BB_succs( bb );
01392 if( edge !=NULL)
01393 BBLIST_freq( edge ) = info_top.freq_edge.Value( );
01394
01395 if( Get_Trace( TP_A_PROF,TT_PROF_FEEDBACK_DUMP ) )
01396 Dump_Edge_Info(bb,edge);
01397
01398 }
01399 void EDGE_PROFILE::Prepare_Call_Init_Return_BB(BB * bb)
01400 {
01401 TN * return_reg_tn;
01402 OP * save_op;
01403 return_reg_tn = Build_Dedicated_TN(ISA_REGISTER_CLASS_integer, RETURN_REG, 8);
01404 save_op = Mk_OP(TOP_mov, _pu_hdr_return_tn, True_TN, return_reg_tn);
01405 if ( TN_is_register(_pu_hdr_return_tn) && TN_is_register(return_reg_tn) )
01406 Set_OP_copy(save_op);
01407 BB_Prepend_Op(bb, save_op);
01408 }
01409
01410 BB* EDGE_PROFILE::Gen_Call_BB( char* function_name, char* str_arg,
01411 INT64 int_arg,int restore_type,int restore_sum )
01412 {
01413 BB *bb=Gen_BB( );
01414 SRCPOS srcpos = REGION_First_BB->ops.last->srcpos;
01415
01416 OP* restore_f_reg;
01417 OP* restore_reg;
01418 OPS* restore_reg_ops = OPS_Create( );
01419 OPS* restore_f_reg_ops = OPS_Create( );
01420
01421 if ( restore_type == 1 )
01422 {
01423 for ( int i = 0; i < restore_sum; i++ )
01424 {
01425 TN* save_reg_tn1 = Gen_Register_TN( ISA_REGISTER_CLASS_integer,8 );
01426 TN* return_result_reg =
01427 Build_Dedicated_TN( ISA_REGISTER_CLASS_integer,RETURN_REG + i ,8 );
01428 Set_TN_is_global_reg( save_reg_tn1 );
01429 restore_reg = Mk_OP( TOP_mov,return_result_reg,True_TN,save_reg_tn1 );
01430 OPS_Insert_Op(restore_reg_ops,NULL,restore_reg,FALSE);
01431 OP* mov_op = Mk_OP( TOP_mov,save_reg_tn1,True_TN,return_result_reg );
01432 BB_Append_Op( bb,mov_op );
01433 }
01434 }
01435
01436 if ( restore_type == 2 )
01437 {
01438 for ( int i = 0 ; i < restore_sum ; i++)
01439 {
01440 TN* save_reg_tn2 = Gen_Register_TN( ISA_REGISTER_CLASS_float,8 );
01441 TN* f_return_result_reg = Build_Dedicated_TN(
01442 ISA_REGISTER_CLASS_float,FLOAT_RETURN_REG + i, 0 );
01443
01444 Set_TN_is_global_reg( save_reg_tn2 );
01445 restore_f_reg = Mk_OP( TOP_mov_f,f_return_result_reg,
01446 True_TN,save_reg_tn2 );
01447 OPS_Insert_Op( restore_f_reg_ops,NULL,restore_f_reg,FALSE );
01448 OP* mov_f_op = Mk_OP( TOP_mov_f,save_reg_tn2,
01449 True_TN,f_return_result_reg );
01450 BB_Append_Op( bb,mov_f_op );
01451 }
01452 }
01453
01454
01455
01456
01457 TN* save_gp_TN = NULL;
01458 save_gp_TN = Find_TN( TOP_mov,1,1,GP_TN,2 );
01459 if ( save_gp_TN != NULL )
01460 {
01461 OP* mov_op = Mk_OP( TOP_mov,GP_TN,True_TN,save_gp_TN );
01462 BB_Append_Op( bb,mov_op );
01463 }
01464
01465
01466
01467
01468
01469 TN* tgt_TN1 = Gen_Register_TN( ISA_REGISTER_CLASS_integer,8 );
01470
01471 TCON tcon = Host_To_Targ_String ( MTYPE_STRING,str_arg,
01472 strlen( str_arg )+1 );
01473 TY_IDX ty = MTYPE_To_TY( MTYPE_STRING );
01474 ST* st = Gen_String_Sym ( &tcon, ty, FALSE );
01475 Allocate_Object( st );
01476 INT64 offset = 0;
01477 INT32 relocs = TN_RELOC_IA_LTOFF22;
01478 TN* var_name_tn = Gen_Symbol_TN ( st , offset, relocs );
01479 OP* addl_op = Mk_OP( TOP_addl,tgt_TN1,True_TN,var_name_tn,GP_TN );
01480 OP_srcpos( addl_op ) = srcpos;
01481 BB_Append_Op( bb,addl_op );
01482
01483 TN * TN_FIRST_OUTPUT_REG = Build_Dedicated_TN(
01484 ISA_REGISTER_CLASS_integer,FIRST_OUTPUT_REG,8 );
01485 TN* enum_ldtype = Gen_Enum_TN( ECV_ldtype );
01486 TN* enum_ldhint = Gen_Enum_TN( ECV_ldhint );
01487 OP* ld8_op = Mk_OP( TOP_ld8,TN_FIRST_OUTPUT_REG,True_TN,
01488 enum_ldtype,enum_ldhint,tgt_TN1 );
01489 OP_srcpos( ld8_op ) = srcpos;
01490 BB_Append_Op( bb,ld8_op );
01491
01492
01493
01494
01495 TN* TN_second_output_reg = Build_Dedicated_TN( ISA_REGISTER_CLASS_integer,
01496 FIRST_OUTPUT_REG - 1, 8 );
01497 TN* literal_TN = Gen_Literal_TN( int_arg,8 );
01498 OP* mov_i_op = Mk_OP( TOP_mov_i,TN_second_output_reg,True_TN,literal_TN );
01499 BB_Append_Op( bb,mov_i_op );
01500
01501
01502
01503
01504
01505 TN* enum_sptk = Gen_Enum_TN( ECV_bwh_sptk );
01506 TN* enum_many = Gen_Enum_TN( ECV_ph_many );
01507 TN* enum_dh = Gen_Enum_TN( ECV_dh );
01508
01509 TN *ar_ec = Build_Dedicated_TN ( ISA_REGISTER_CLASS_application,
01510 ( REGISTER )( REGISTER_MIN + 66 ),
01511 8 );
01512 ty = Make_Function_Type( MTYPE_To_TY( MTYPE_V ) );
01513 ST *call_st = Gen_Intrinsic_Function( ty, function_name );
01514 Clear_PU_no_side_effects( Pu_Table[ST_pu( call_st )] );
01515 Clear_PU_is_pure( Pu_Table[ST_pu( call_st )] );
01516 Set_PU_no_delete( Pu_Table[ST_pu( call_st )] );
01517 TN *function_name_tn = Gen_Symbol_TN( call_st,0,0 );
01518 OP* call_op =Mk_OP( TOP_br_call,RA_TN,True_TN,enum_sptk,enum_many,enum_dh,
01519 function_name_tn,ar_ec );
01520
01521 BB_Append_Op( bb,call_op );
01522 if ( restore_type == 1 )
01523 {
01524 BB_Append_Ops( bb,restore_reg_ops );
01525 }else if ( restore_type == 2 )
01526 {
01527 BB_Append_Ops( bb,restore_f_reg_ops );
01528 }
01529
01530 Set_BB_call( bb );
01531
01532
01533 WN *count = WN_Intconst( MTYPE_I4, int_arg );
01534 WN *str_arg_tn = WN_LdaString( str_arg, 0,
01535 strlen( str_arg ) + 1 );
01536 WN* call = Gen_Call( function_name, str_arg_tn ,count );
01537 call_st = WN_st( call );
01538 CALLINFO* call_info = TYPE_PU_ALLOC ( CALLINFO );
01539 CALLINFO_call_st( call_info ) = call_st;
01540 CALLINFO_call_wn( call_info ) = call;
01541 BB_Add_Annotation ( bb, ANNOT_CALLINFO, call_info );
01542 return bb;
01543 }
01544
01545 BB* EDGE_PROFILE::Gen_Call_BB( char* function_name, TN * PU_Handle,
01546 INT64 int_arg,int restore_type,int restore_sum )
01547 {
01548 BB *bb=Gen_BB( );
01549 SRCPOS srcpos = REGION_First_BB->ops.last->srcpos;
01550
01551 OP* restore_f_reg;
01552 OP* restore_reg;
01553 OPS* restore_reg_ops = OPS_Create( );
01554 OPS* restore_f_reg_ops = OPS_Create( );
01555
01556 if ( restore_type == 1 )
01557 {
01558 for ( int i = 0; i < restore_sum; i++ )
01559 {
01560 TN* save_reg_tn1 = Gen_Register_TN( ISA_REGISTER_CLASS_integer,8 );
01561 TN* return_result_reg =
01562 Build_Dedicated_TN( ISA_REGISTER_CLASS_integer,RETURN_REG + i ,8 );
01563 Set_TN_is_global_reg( save_reg_tn1 );
01564 restore_reg = Mk_OP( TOP_mov,return_result_reg,True_TN,save_reg_tn1 );
01565 OPS_Insert_Op(restore_reg_ops,NULL,restore_reg,FALSE);
01566 OP* mov_op = Mk_OP( TOP_mov,save_reg_tn1,True_TN,return_result_reg );
01567 BB_Append_Op( bb,mov_op );
01568 }
01569 }
01570
01571 if ( restore_type == 2 )
01572 {
01573 for ( int i = 0 ; i < restore_sum ; i++)
01574 {
01575 TN* save_reg_tn2 = Gen_Register_TN( ISA_REGISTER_CLASS_float,8 );
01576 TN* f_return_result_reg = Build_Dedicated_TN(
01577 ISA_REGISTER_CLASS_float,FLOAT_RETURN_REG + i, 0 );
01578
01579 Set_TN_is_global_reg( save_reg_tn2 );
01580 restore_f_reg = Mk_OP( TOP_mov_f,f_return_result_reg,
01581 True_TN,save_reg_tn2 );
01582 OPS_Insert_Op( restore_f_reg_ops,NULL,restore_f_reg,FALSE );
01583 OP* mov_f_op = Mk_OP( TOP_mov_f,save_reg_tn2,
01584 True_TN,f_return_result_reg );
01585 BB_Append_Op( bb,mov_f_op );
01586 }
01587 }
01588
01589
01590
01591
01592 TN* save_gp_TN = NULL;
01593 save_gp_TN = Find_TN( TOP_mov,1,1,GP_TN,2 );
01594 if ( save_gp_TN != NULL )
01595 {
01596 OP* mov_op = Mk_OP( TOP_mov,GP_TN,True_TN,save_gp_TN );
01597 BB_Append_Op( bb,mov_op );
01598 }
01599
01600
01601
01602
01603
01604 TN* TN_FIRST_OUTPUT_REG = Build_Dedicated_TN( ISA_REGISTER_CLASS_integer,
01605 FIRST_OUTPUT_REG, 8 );
01606 OP* mov_op = Mk_OP( TOP_mov,TN_FIRST_OUTPUT_REG,True_TN,_pu_hdr_return_tn);
01607 BB_Append_Op( bb,mov_op );
01608
01609
01610
01611
01612 TN* TN_second_output_reg = Build_Dedicated_TN( ISA_REGISTER_CLASS_integer,
01613 FIRST_OUTPUT_REG - 1, 8 );
01614 TN* literal_TN = Gen_Literal_TN( int_arg,8 );
01615 OP* mov_i_op = Mk_OP( TOP_mov_i,TN_second_output_reg,True_TN,literal_TN );
01616 BB_Append_Op( bb,mov_i_op );
01617
01618
01619
01620
01621
01622 TN* enum_sptk = Gen_Enum_TN( ECV_bwh_sptk );
01623 TN* enum_many = Gen_Enum_TN( ECV_ph_many );
01624 TN* enum_dh = Gen_Enum_TN( ECV_dh );
01625
01626 TN *ar_ec = Build_Dedicated_TN ( ISA_REGISTER_CLASS_application,
01627 ( REGISTER )( REGISTER_MIN + 66 ),
01628 8 );
01629 TY_IDX ty = MTYPE_To_TY( MTYPE_STRING );
01630 ty = Make_Function_Type( MTYPE_To_TY( MTYPE_V ) );
01631 ST *call_st = Gen_Intrinsic_Function( ty, function_name );
01632 Clear_PU_no_side_effects( Pu_Table[ST_pu( call_st )] );
01633 Clear_PU_is_pure( Pu_Table[ST_pu( call_st )] );
01634 Set_PU_no_delete( Pu_Table[ST_pu( call_st )] );
01635 TN *function_name_tn = Gen_Symbol_TN( call_st,0,0 );
01636 OP* call_op =Mk_OP( TOP_br_call,RA_TN,True_TN,enum_sptk,enum_many,enum_dh,
01637 function_name_tn,ar_ec );
01638
01639 BB_Append_Op( bb,call_op );
01640 if ( restore_type == 1 )
01641 {
01642 BB_Append_Ops( bb,restore_reg_ops );
01643 }else if ( restore_type == 2 )
01644 {
01645 BB_Append_Ops( bb,restore_f_reg_ops );
01646 }
01647
01648 Set_BB_call( bb );
01649
01650
01651 WN * arg1 = WN_Intconst( MTYPE_I8, 0 );
01652 WN * arg2 = WN_Intconst( MTYPE_I8, int_arg);
01653 WN* call = Gen_Call( function_name, arg1 ,arg2 );
01654 call_st = WN_st( call );
01655 CALLINFO* call_info = TYPE_PU_ALLOC ( CALLINFO );
01656 CALLINFO_call_st( call_info ) = call_st;
01657 CALLINFO_call_wn( call_info ) = call;
01658 BB_Add_Annotation ( bb, ANNOT_CALLINFO, call_info );
01659 return bb;
01660 }
01661
01662
01663 BB* EDGE_PROFILE::Gen_Instru_Call_BB( char* function_name,
01664 char* file_pu_name,INT64 id )
01665 {
01666 return Gen_Call_BB( function_name,_pu_hdr_return_tn,id,0 );
01667 }
01668
01669 BB* EDGE_PROFILE::Gen_PU_Init_Call_BB( char* function_name,char* file_pu_name,
01670 INT64 _instrument_count )
01671 {
01672 return Gen_Call_BB( function_name,file_pu_name,_instrument_count,0 );
01673 }
01674
01675
01676 TN* EDGE_PROFILE::Find_TN( TOP opc,int bb_num,int TN_num, TN* t1, int index )
01677 {
01678 Is_True( bb_num>0,( "the BB num is not less than 0" ) );
01679 Is_True( TN_num>=0,( " the TN num is not less than 0" ) );
01680 Is_True( index>=0,( " the TN num is not less than 0" ) );
01681 Is_True( index<=9,( " the TN num is not less than 9" ) );
01682 BB* bb=_pu_first_bb;
01683 for( int i=1; i<bb_num; i++ )
01684 if( bb != NULL )
01685 bb = BB_next( bb );
01686
01687 if ( bb == NULL )
01688 return NULL;
01689
01690 OP* opcode = bb->ops.first;
01691 for( ; opcode != NULL; opcode = OP_next( opcode ) )
01692 {
01693 if ( OP_code( opcode ) != opc )
01694 continue;
01695
01696 if ( OP_opnd( opcode,TN_num ) != t1 )
01697 continue;
01698 else
01699 return OP_opnd( opcode,index );
01700 }
01701
01702 if ( opcode == NULL )
01703 return NULL;
01704 }
01705
01706 BOOL EDGE_PROFILE::BB_Is_In_BBLIST( BBLIST* bblst,BB* bb,BB* before_bb )
01707 {
01708 for( BBLIST* tbblist = bblst;
01709 tbblist != NULL && BBLIST_item( tbblist ) != before_bb;
01710 tbblist = BBLIST_next( tbblist ) )
01711 {
01712 if( BBLIST_item( tbblist ) == bb )
01713 return TRUE;
01714 }
01715 return FALSE;
01716 }
01717
01718 BOOL EDGE_PROFILE::BB_Is_For_Instru(BB* bb)
01719 {
01720 BB* bb1;
01721 if(BB_profile_added(bb))
01722 return FALSE;
01723
01724 if(BB_profile_splitted(bb))
01725 {
01726 mBB_NUM id_before_profile = BB_id_before_profile(bb);
01727 for(bb1=bb; bb1 !=NULL; bb1=BB_next(bb1))
01728 {
01729 if (id_before_profile == BB_id_before_profile(bb1))
01730 break;
01731 }
01732 if (id_before_profile == BB_id_before_profile(bb1))
01733 return FALSE;
01734 }
01735 return TRUE;
01736 }
01737 TN* EDGE_PROFILE::Find_TN_in_BB( TOP opc, BB* in, int i1, TN* t1, int index )
01738 {
01739 Is_True( in != NULL,( "the BB should not be NULL" ) );
01740 Is_True( i1>=0,( " the TN num is not less than 0" ) );
01741 Is_True( index>=0,( " the TN num is not less than 0" ) );
01742 Is_True( index<=9,( " the TN num is not less than 9" ) );
01743
01744 OP* opcode = in->ops.first;
01745 for( ; opcode != NULL; opcode = OP_next( opcode ) )
01746 {
01747 if ( OP_code( opcode ) != opc )
01748 continue;
01749
01750 if ( OP_opnd( opcode,i1 ) != t1 )
01751 continue;
01752 else
01753 return OP_opnd( opcode,index );
01754 }
01755
01756 if ( opcode == NULL )
01757 return NULL;
01758 }
01759
01760 void EDGE_PROFILE::Prepare_Instrument( )
01761 {
01762 Require_And_Alloc_Reg( );
01763
01764
01765
01766
01767
01768
01769 OP* save_ar_pfs = REGION_First_BB->ops.first;
01770 TN* save_ar_pfs_TN = OP_result( save_ar_pfs,0 );
01771 TN* save_gp_TN = NULL;
01772 OP* save_gp_op = NULL;
01773 save_gp_TN = Find_TN( TOP_mov,1,1,GP_TN,2 );
01774 if(save_gp_TN == NULL)
01775 {
01776 save_gp_TN = Gen_Register_TN( ISA_REGISTER_CLASS_integer,8 );
01777 Set_TN_is_global_reg(save_gp_TN);
01778 for ( BB_LIST *elist = Entry_BB_Head; elist; elist = BB_LIST_rest( elist ) )
01779 {
01780 BB* entry_bb= BB_LIST_first( elist );
01781 save_gp_op = Mk_OP(TOP_mov,save_gp_TN,True_TN,GP_TN);
01782 save_gp_op->bb = entry_bb;
01783 BB_Insert_Op(entry_bb,entry_bb->ops.first->next,
01784 save_gp_op,false);
01785 }
01786 }
01787
01788 Is_True( save_ar_pfs_TN != NULL,( "there should be a IR that alloc pfs" ) );
01789
01790 BB* exit_bb = _pu_last_bb;
01791 TN* pfs_tn = Find_TN( TOP_mov_t_ar_r_i,PU_BB_Count,2,Pfs_TN,2 );
01792 OP* mov_t_ar_r_op;
01793 if ( NULL == pfs_tn )
01794 {
01795 mov_t_ar_r_op = Mk_OP( TOP_mov_t_ar_r_i,Pfs_TN,True_TN,save_ar_pfs_TN );
01796 for ( BB_LIST *elist = Exit_BB_Head; elist; elist = BB_LIST_rest( elist ) )
01797 {
01798 exit_bb = BB_LIST_first( elist );
01799 mov_t_ar_r_op = Mk_OP( TOP_mov_t_ar_r_i,Pfs_TN,True_TN,save_ar_pfs_TN );
01800 if ( exit_bb->ops.last->prev != NULL )
01801 BB_Insert_Op_After( exit_bb, exit_bb->ops.last->prev ,mov_t_ar_r_op );
01802 else
01803 BB_Insert_Op_After( exit_bb, exit_bb->ops.last,mov_t_ar_r_op );
01804 }
01805 }
01806 }
01807
01808 void EDGE_PROFILE::Require_And_Alloc_Reg( )
01809 {
01810 REGISTER_Allocate_Stacked_Register( ABI_PROPERTY_caller,
01811 ISA_REGISTER_CLASS_integer, FIRST_OUTPUT_REG );
01812 REGISTER_Allocate_Stacked_Register( ABI_PROPERTY_caller,
01813 ISA_REGISTER_CLASS_integer, FIRST_OUTPUT_REG - 1 );
01814 REGISTER_Allocate_Stacked_Register( ABI_PROPERTY_caller,
01815 ISA_REGISTER_CLASS_integer, FIRST_OUTPUT_REG - 2 );
01816 }
01817
01818
01819
01820
01821
01822 INT32 Curr_PU_BB_Count( )
01823 {
01824 INT32 count = 0;
01825 for( BB* bb = REGION_First_BB; bb != NULL; bb = BB_next( bb ) )
01826 ++count;
01827 return count;
01828 }
01829
01830 void Init_CFG( )
01831 {
01832 for( BB* bb = REGION_First_BB; bb != NULL; bb = BB_next( bb ) )
01833 for( BBLIST* out_edge = BB_succs( bb ); out_edge != NULL;
01834 out_edge = BBLIST_next( out_edge ) )
01835 BBLIST_freq( out_edge ) = FB_FREQ_UNINIT;
01836 }
01837
01838 void EDGE_PROFILE::Propagate( )
01839 {
01840 for( BB* bb = _pu_first_bb; bb != NULL; bb = BB_next( bb ) )
01841 {
01842 Propagate_Node_In( bb );
01843 Propagate_Node_Out( bb );
01844 }
01845 }
01846
01847
01848
01849
01850 void EDGE_PROFILE::Propagate_Node_In( BB* bb )
01851 {
01852 FB_FREQ total_in,total_out;
01853 int uninit_in, uninit_out;
01854 total_in = total_out = FB_FREQ_ZERO;
01855 uninit_in = uninit_out = 0;
01856 BOOL has_in_edge = FALSE;
01857
01858
01859 for( BBLIST* in_edge = BB_preds( bb ); in_edge != NULL;
01860 in_edge = BBLIST_next( in_edge ) )
01861 {
01862 has_in_edge = TRUE;
01863 float freq = Freq( BBLIST_item( in_edge ),bb );
01864 if ( UNINIT_FREQ( freq ) )
01865 {
01866 ++uninit_in;
01867 break;
01868 }
01869 else
01870 total_in += FB_FREQ( freq,TRUE );
01871 }
01872
01873
01874
01875 if( uninit_in == 0 && has_in_edge )
01876 {
01877 BB_freq( bb ) = total_in.Value( );
01878
01879
01880 for ( BBLIST* out_edge = BB_succs( bb ); out_edge != NULL;
01881 out_edge = BBLIST_next( out_edge ) )
01882 {
01883 float freq = Freq( bb,BBLIST_item( out_edge ) );
01884 if( UNINIT_FREQ( freq ) )
01885 ++uninit_out;
01886 else
01887 total_out += FB_FREQ( freq,TRUE );
01888 }
01889
01890 if ( uninit_out == 1 )
01891 {
01892 for ( BBLIST* out_edge = BB_succs( bb ); out_edge != NULL;
01893 out_edge = BBLIST_next( out_edge ) )
01894 {
01895 float freq = Freq( bb,BBLIST_item( out_edge ) );
01896 if( UNINIT_FREQ( freq ) )
01897 {
01898 Set_Freq( bb,BBLIST_item( out_edge ),
01899 total_in.Value( ) - total_out.Value( ) );
01900 Propagate_Node_In( BBLIST_item( out_edge ) );
01901 break;
01902 }
01903 }
01904 }
01905 }
01906 }
01907
01908
01909
01910
01911 void EDGE_PROFILE::Propagate_Node_Out( BB* bb )
01912 {
01913 FB_FREQ total_in,total_out;
01914 int uninit_in, uninit_out;
01915 total_in = total_out = FB_FREQ_ZERO;
01916 uninit_in = uninit_out = 0;
01917 BOOL has_out_edge = FALSE;
01918
01919
01920 for( BBLIST* out_edge = BB_succs( bb ); out_edge != NULL;
01921 out_edge = BBLIST_next( out_edge ) )
01922 {
01923 has_out_edge = TRUE;
01924 float freq = Freq( bb,BBLIST_item( out_edge ) );
01925 if ( UNINIT_FREQ( freq ) )
01926 {
01927 ++uninit_out;
01928 break;
01929 }
01930 else
01931 total_out += FB_FREQ( freq,TRUE );
01932 }
01933
01934
01935
01936 if( uninit_out == 0 && has_out_edge )
01937 {
01938 BB_freq( bb ) = total_out.Value( );
01939
01940
01941 for ( BBLIST* in_edge = BB_preds( bb ); in_edge != NULL;
01942 in_edge = BBLIST_next( in_edge ) )
01943 {
01944 float freq = Freq( BBLIST_item( in_edge ),bb );
01945 if( UNINIT_FREQ( freq ) )
01946 ++uninit_in;
01947 else
01948 total_in += FB_FREQ( freq,TRUE );
01949 }
01950
01951 if ( uninit_in == 1 )
01952 {
01953 for ( BBLIST* in_edge = BB_preds( bb ); in_edge != NULL;
01954 in_edge = BBLIST_next( in_edge ) )
01955 {
01956 float freq = Freq( BBLIST_item( in_edge ),bb );
01957 if( UNINIT_FREQ( freq ) )
01958 {
01959 Set_Freq( BBLIST_item( in_edge ),bb,
01960 total_out.Value( ) - total_in.Value( ) );
01961 Propagate_Node_Out( BBLIST_item( in_edge ) );
01962 break;
01963 }
01964 }
01965
01966 }
01967 }
01968 }
01969
01970
01971
01972
01973
01974
01975 void Compute_Edge_Freq_Base_Prob( )
01976 {
01977 for( BB* bb = REGION_First_BB; bb != NULL; bb = BB_next( bb ) )
01978 {
01979 for( BBLIST* out_edge = BB_succs( bb ); out_edge != NULL;
01980 out_edge = BBLIST_next( out_edge ) )
01981 {
01982 if ( ERROR_FREQ( BB_freq( bb ) ) )
01983 DevWarn( "there a bb with invalid freq,BB id %d",BB_id( bb ) );
01984 else if ( ERROR_PROB( BBLIST_prob( out_edge ) ) )
01985 {
01986 DevWarn( "there a edge with invalid prob" );
01987 BBLIST_prob( out_edge ) = 0.0;
01988 BBLIST_freq( out_edge ) = 0.0;
01989 }
01990 else
01991 BBLIST_freq( out_edge ) = BBLIST_prob( out_edge ) * BB_freq( bb );
01992 }
01993 }
01994 }
01995
01996
01997
01998
01999
02000
02001 void Compute_Edge_Prob_Base_Freq( )
02002 {
02003 INT32 len = 1;
02004 for( BB* bb = REGION_First_BB; bb != NULL; bb = BB_next( bb ) )
02005 {
02006 BBLIST* out_edge = BB_succs( bb );
02007 if ( out_edge != NULL )
02008 len = BBlist_Len( out_edge );
02009 for( out_edge = BB_succs( bb ); out_edge != NULL;
02010 out_edge = BBLIST_next( out_edge ) )
02011 {
02012 if ( ERROR_FREQ( BB_freq( bb ) ) )
02013 DevWarn( "there a bb with invalid freq,BB id %d",BB_id( bb ) );
02014 else if ( ERROR_FREQ( BBLIST_freq( out_edge ) ) )
02015 DevWarn( "there a edge with invalid prob" );
02016 else if ( ZERO_FREQ( BB_freq( bb ) ) )
02017 {
02018 BBLIST_prob( out_edge ) = 1.0F / len;
02019 }
02020 else
02021 BBLIST_prob( out_edge ) = BBLIST_freq( out_edge ) / BB_freq( bb );
02022 }
02023 }
02024 }
02025
02026 void Change_BB_Label( BB* bb,LABEL_IDX i )
02027 {
02028 Set_Label_BB( i,bb );
02029 ANNOTATION* annt = ANNOT_Get( BB_annotations( bb ),ANNOT_LABEL );
02030 if ( annt != NULL )
02031 {
02032 BB_annotations( bb ) = ANNOT_Unlink( BB_annotations( bb ), annt );
02033 BB_Add_Annotation( bb,ANNOT_LABEL,(void *)(INTPTR)i);
02034 }
02035 }
02036
02037 BB* First_Branch_BB( )
02038 {
02039 BB* bb = NULL;
02040 for( bb = REGION_First_BB; bb != NULL; bb =BB_next( bb ) )
02041 {
02042 if( BB_kind( bb ) == BBKIND_LOGIF || BB_kind( bb ) == BBKIND_VARGOTO ||
02043 BB_kind( bb ) == BBKIND_INDGOTO )
02044 return bb;
02045 }
02046 return bb;
02047 }
02048
02049 BOOL Result_Tn_In_BB( BB* bb, TN* tn )
02050 {
02051 OP* opcode = bb->ops.first;
02052 int i;
02053 for( ; opcode != NULL; opcode = OP_next( opcode ) )
02054 {
02055 for ( i = 0; i < OP_results( opcode ); i++ )
02056 {
02057 if ( tn == OP_result( opcode,i ) )
02058 return TRUE;
02059 }
02060 }
02061 return FALSE;
02062 }
02063
02064 BOOL Opnd_Tn_In_BB( BB* bb, TN* tn )
02065 {
02066 OP* opcode = bb->ops.first;
02067 int i;
02068 for( ; opcode != NULL; opcode = OP_next( opcode ) )
02069 {
02070 for ( i = 0; i < OP_opnds( opcode ); i++ )
02071 {
02072 if ( tn == OP_opnd( opcode,i ) )
02073 {
02074 return TRUE;
02075 }
02076 }
02077 }
02078 return FALSE;
02079 }
02080
02081 LABEL_IDX Get_Br_Op_Tgt_Label( OP* branch_op )
02082 {
02083 INT tn_num = OP_opnds( branch_op );
02084 for( int i = 0; i<tn_num; i++ )
02085 {
02086 TN* tgt_tn = OP_opnd( branch_op, i );
02087 if( TN_is_label( tgt_tn ) )
02088 {
02089 return TN_label( tgt_tn );
02090 }
02091 }
02092 return LABEL_IDX_NONE;
02093 }
02094
02095
02096 INT32 Get_Return_Reg_Sum(BB* bb)
02097 {
02098 for ( int i = 3; i >= 0; i-- )
02099 {
02100 TN* return_result_reg =
02101 Build_Dedicated_TN( ISA_REGISTER_CLASS_integer,RETURN_REG + i, 8);
02102
02103 OP* opcode = bb->ops.first;
02104 int j;
02105 for( ; opcode != NULL; opcode = OP_next( opcode ))
02106 {
02107 for ( j = 0; j < OP_opnds( opcode ); j++ )
02108 {
02109 if ( return_result_reg == OP_opnd( opcode,j ) )
02110 {
02111 return i+1;
02112 }
02113 }
02114 for ( j = 0; j < OP_results( opcode ); j++)
02115 {
02116 if ( return_result_reg == OP_result( opcode,j ) )
02117 {
02118 opcode = bb->ops.last;
02119 break;
02120 }
02121 }
02122 }
02123 }
02124 return 0;
02125 }
02126
02127
02128 INT32 Get_Float_Return_Reg_Sum(BB* bb)
02129 {
02130 for ( int i = 7 ; i >= 0; i-- )
02131 {
02132 TN* f_return_result_reg =
02133 Build_Dedicated_TN( ISA_REGISTER_CLASS_float,FLOAT_RETURN_REG + i, 0);
02134
02135 OP* opcode = bb->ops.first;
02136 int j;
02137 for( ; opcode != NULL; opcode = OP_next( opcode ))
02138 {
02139 for ( j = 0; j < OP_opnds( opcode ); j++ )
02140 {
02141 if ( f_return_result_reg == OP_opnd( opcode,j ) )
02142 {
02143 return i+1;
02144 }
02145 }
02146 for ( j = 0; j < OP_results( opcode ); j++)
02147 {
02148 if ( f_return_result_reg == OP_result( opcode,j ) )
02149 {
02150 opcode = bb->ops.last;
02151 break;
02152 }
02153 }
02154 }
02155 }
02156 return 0;
02157 }