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
00056
00057
00058 #ifdef USE_PCH
00059 #include "opt_pch.h"
00060 #endif // USE_PCH
00061 #pragma hdrstop
00062
00063
00064 #ifdef _KEEP_RCS_ID
00065 #define opt_rvi_emit_CXX "opt_rvi_emit.cxx"
00066 static char *rcs_id = opt_rvi_emit_CXX"$Revision$";
00067 #endif
00068
00069 #include "defs.h"
00070 #include "errors.h"
00071 #include "erglob.h"
00072 #include "tracing.h"
00073 #include "wn.h"
00074 #include "region_util.h"
00075 #include "cxx_memory.h"
00076
00077 #include "opt_defs.h"
00078 #include "opt_config.h"
00079 #include "opt_base.h"
00080 #include "opt_bb.h"
00081 #include "opt_cfg.h"
00082 #include "opt_rvi.h"
00083 #include "opt_rviwn.h"
00084 #include "opt_rvi_emit.h"
00085 #include "opt_alias_mgr.h"
00086
00087
00088
00089
00090
00091 void
00092 RVI_EMIT::Emit_bb( BB_NODE *bb )
00093 {
00094 if ( Rvi()->Tracing() )
00095 fprintf( TFile, "RVI_EMIT::Emit_bb(BB:%d)\n", bb->Id() );
00096
00097 if (bb->Kind() == BB_ENTRY && bb->Entrywn()) {
00098 const OPCODE fopc = WN_opcode(bb->Entrywn());
00099 if ( fopc == OPC_FUNC_ENTRY ) {
00100 Set_entry_wn(bb->Entrywn());
00101 }
00102 else if ( fopc == OPC_ALTENTRY ) {
00103
00104
00105 bb->Prepend_wn_after_labels( bb->Entrywn() );
00106 }
00107 else if ( fopc == OPC_LABEL &&
00108 WN_Label_Is_Handler_Begin(bb->Entrywn()) )
00109 {
00110
00111
00112 bb->Prepend_wn_after_labels( bb->Entrywn() );
00113 }
00114 #ifdef KEY
00115 else if ( fopc == OPC_LABEL &&
00116 LABEL_target_of_goto_outer_block(WN_label_number(bb->Entrywn())))
00117 {
00118
00119
00120 bb->Prepend_wn_after_labels( bb->Entrywn() );
00121 }
00122 #endif
00123 }
00124
00125 WN *first = bb->Firststmt();
00126 WN *last = bb->Laststmt();
00127
00128 if ( first == NULL ) {
00129 Is_True( last == NULL,
00130 ("RVI_EMIT::Emit_bb: non-NULL last for BB:%d", bb->Id()) );
00131 Is_Trace( Rvi()->Tracing(),
00132 (TFile,"RVI_EMIT::Emit_bb, empty BB%d\n",bb->Id()));
00133 return;
00134 }
00135
00136 if ( Last_wn() != NULL ) {
00137 WN_prev(first) = Last_wn();
00138 WN_next(Last_wn()) = first;
00139 WN_next(last) = NULL;
00140 Set_last_wn( last );
00141 }
00142 else {
00143
00144 Set_first_wn( first );
00145 Set_last_wn( last );
00146 }
00147 }
00148
00149
00150
00151
00152
00153 void
00154 RVI_EMIT::Emit_bb_annotations( BB_NODE *bb )
00155 {
00156 if ( Rvi()->Tracing() ) {
00157 fprintf( TFile, "RVI_EMIT::Emit_bb_annotations(BB:%d)\n", bb->Id());
00158 }
00159
00160 WN *first = bb->Firststmt();
00161 if ( first == NULL ) {
00162
00163 Is_True( bb->Rvi_anns() == NULL || bb->Rvi_anns()->Is_Empty(),
00164 ("RVI_EMIT::Emit_bb_annotations: annotations in empty bb:%d",
00165 bb->Id()) );
00166
00167 return;
00168 }
00169
00170 STMT_ITER stmt_iter;
00171 WN *wn;
00172 if ( ! Lda_only() ) {
00173 FOR_ALL_ELEM( wn, stmt_iter, Init(bb->Firststmt(),bb->Laststmt()) ){
00174 WN *new_kid;
00175 Emit_wn_annotations( bb, wn, &new_kid );
00176 Is_True( new_kid == NULL,
00177 ("RVI_EMIT::Get_bb_annotations: statement can't be replaced") );
00178 }
00179 }
00180 else {
00181
00182 FOR_ALL_ELEM( wn, stmt_iter, Init(bb->Firststmt(),bb->Laststmt()) ){
00183 WN *new_kid;
00184 Emit_lda_wn_annotations( bb, wn, &new_kid );
00185 Is_True( new_kid == NULL,
00186 ("RVI_EMIT::Get_bb_annotations: statement can't be replaced") );
00187 }
00188 }
00189
00190
00191 }
00192
00193
00194
00195
00196
00197
00198 void
00199 RVI_EMIT::Emit_wn_annotations( BB_NODE *bb, WN *wn, WN **new_wn ) const
00200 {
00201 const OPCODE opc = WN_opcode(wn);
00202 const OPERATOR opr = OPCODE_operator(opc);
00203 IDX_32 bitpos;
00204 RVI_ANN *annotation;
00205
00206
00207 *new_wn = NULL;
00208
00209
00210 if ( ! Rvi()->Black_box(opc) ) {
00211
00212 for ( INT ikid = 0; ikid < WN_kid_count(wn); ikid++ ) {
00213 WN *new_kid;
00214 #ifdef KEY // bug 12471: __builtin_expect's first kid must be constant
00215 if (WN_operator(wn) == OPR_INTRINSIC_OP &&
00216 ((INTRINSIC) WN_intrinsic(wn)) == INTRN_EXPECT &&
00217 ikid == 1)
00218 continue;
00219 #endif
00220 Emit_wn_annotations( bb, WN_kid(wn,ikid), &new_kid );
00221
00222
00223 if ( new_kid != NULL ) {
00224 WN_kid(wn,ikid) = new_kid;
00225 }
00226 }
00227 }
00228
00229 switch ( opr ) {
00230 case OPR_CONST:
00231 case OPR_INTCONST:
00232 case OPR_LDA:
00233
00234 bitpos = Rvi()->Get_bitpos(wn);
00235 if ( bitpos != ILLEGAL_BP ) {
00236 if ( (annotation = bb->Rvi_anns()->Find( bitpos )) != NULL ) {
00237 *new_wn = annotation->New_ldid( Alias_Mgr() );
00238 }
00239 }
00240 break;
00241
00242 case OPR_LDID:
00243 if ( ST_class(WN_st(wn)) == CLASS_PREG ) {
00244
00245 break;
00246 }
00247 bitpos = Rvi()->Get_bitpos( wn );
00248 if ( bitpos != ILLEGAL_BP ) {
00249 if ( (annotation = bb->Rvi_anns()->Find( bitpos )) != NULL ) {
00250 WN_load_offset(wn) = annotation->Preg();
00251 WN_st_idx(wn) = ST_st_idx(annotation->Preg_st());
00252 WN_set_ty(wn, annotation->Preg_ty());
00253 Alias_Mgr()->Gen_alias_id(wn, NULL);
00254
00255
00256
00257
00258
00259 OPCODE load_opc = WN_opcode(annotation->Rvi_node()->Loadwn());
00260 if ( load_opc != opc ) {
00261 *new_wn = Rvi()->Load_from_preg_cvtl( wn, load_opc );
00262
00263 }
00264 }
00265 }
00266 break;
00267
00268 case OPR_STID:
00269 if ( ST_class(WN_st(wn)) == CLASS_PREG ) {
00270
00271 break;
00272 }
00273 bitpos = Rvi()->Get_bitpos( wn );
00274 if ( bitpos != ILLEGAL_BP ) {
00275 if ( (annotation = bb->Rvi_anns()->Find( bitpos )) != NULL ) {
00276
00277
00278
00279
00280 if ( Rvi()->Get_chi_list(wn) != NULL ) {
00281 Rvi()->Store_to_preg_and_mem(bb, wn,
00282 annotation->Preg_st(),
00283 annotation->Preg_ty(),
00284 annotation->Preg() );
00285 }
00286 else {
00287
00288
00289 Rvi()->Store_to_preg_cvtl(wn, annotation->Preg_st(),
00290 annotation->Preg_ty(),
00291 annotation->Preg() );
00292
00293 }
00294 }
00295 }
00296 break;
00297
00298 default:
00299 break;
00300 }
00301
00302 }
00303
00304
00305
00306
00307
00308
00309 void
00310 RVI_EMIT::Emit_lda_wn_annotations( BB_NODE *bb, WN *wn, WN **new_wn ) const
00311 {
00312 const OPCODE opc = WN_opcode(wn);
00313 const OPERATOR opr = OPCODE_operator(opc);
00314 IDX_32 bitpos;
00315 RVI_ANN *annotation;
00316
00317
00318 *new_wn = NULL;
00319
00320
00321 if ( ! Rvi()->Black_box(opc) ) {
00322
00323 for ( INT ikid = 0; ikid < WN_kid_count(wn); ikid++ ) {
00324
00325
00326
00327 if (WN_operator(WN_kid(wn,ikid)) != OPR_LDA ||
00328 Rvi()->Is_lda_candidate(wn, WN_kid(wn,ikid), ikid))
00329 {
00330 WN *new_kid;
00331
00332 Emit_lda_wn_annotations( bb, WN_kid(wn,ikid), &new_kid );
00333
00334
00335 if ( new_kid != NULL ) {
00336 WN_kid(wn,ikid) = new_kid;
00337 }
00338 }
00339 }
00340 }
00341
00342 if ( opr == OPR_LDA ) {
00343
00344 bitpos = Rvi()->Get_bitpos(wn);
00345 if ( bitpos != ILLEGAL_BP ) {
00346 if ( (annotation = bb->Rvi_anns()->Find( bitpos )) != NULL ) {
00347 *new_wn = annotation->New_ldid( Alias_Mgr() );
00348 }
00349 }
00350 }
00351
00352 }
00353
00354
00355
00356
00357
00358
00359 void
00360 RVI_EMIT::Push_region( BB_NODE *start_region )
00361 {
00362 BB_REGION *bb_region = start_region->Regioninfo();
00363 BB_NODE *end_region = bb_region->Region_end();
00364
00365 RVIE_REGION *rvie_region =
00366 CXX_NEW(RVIE_REGION(start_region, end_region, Last_wn()),
00367 Rvi()->Rvi_ppool());
00368
00369 _region_stack.Push(rvie_region);
00370 }
00371
00372 void
00373 RVI_EMIT::Pop_region( void )
00374 {
00375 RVIE_REGION *rvie_region = _region_stack.Pop();
00376 WN *prev_wn = rvie_region->Prev_wn();
00377 WN *last_region_wn = Last_wn();
00378 WN *first_region_wn= prev_wn ? WN_next(prev_wn) : First_wn();
00379 BB_REGION *bb_region = rvie_region->Region_start()->Regioninfo();
00380
00381
00382 if (RID_TYPE_guard(bb_region->Rid()) && first_region_wn == NULL &&
00383 (last_region_wn == NULL || last_region_wn == prev_wn)){
00384 first_region_wn = last_region_wn = WN_CreateComment("EH GUARD REGION");
00385 }
00386
00387 if (first_region_wn == NULL &&
00388 (last_region_wn == NULL || last_region_wn == prev_wn))
00389 {
00390
00391
00392
00393 BB_NODE *rstart = bb_region->Region_start();
00394
00395
00396
00397
00398 last_region_wn = NULL;
00399 rstart->Set_firststmt(NULL);
00400 rstart->Set_laststmt(NULL);
00401
00402
00403
00404 RID_Delete2(bb_region->Rid());
00405 }
00406 else
00407 {
00408
00409 WN *region_body = WN_CreateBlock();
00410 WN_first(region_body) = first_region_wn;
00411 WN_last(region_body) = last_region_wn;
00412 WN *region_wn = WN_CreateRegion(REGION_type_to_kind(bb_region->Rid()),
00413 region_body,
00414 bb_region->Region_pragma_list(),
00415 bb_region->Region_exit_list(),
00416 RID_id(bb_region->Rid()),
00417 bb_region->Ereg_supp());
00418
00419
00420
00421
00422
00423
00424 if ( first_region_wn != NULL )
00425 WN_prev(first_region_wn) = NULL;
00426 Is_True( last_region_wn == NULL || WN_next(last_region_wn) == NULL,
00427 ("RVI_EMIT::Pop_region: last_region_wn has non-null next") );
00428
00429 if ( prev_wn != NULL )
00430 WN_next(prev_wn) = region_wn;
00431 WN_prev(region_wn) = prev_wn;
00432 Set_last_wn(region_wn);
00433
00434 if ( first_region_wn == First_wn() )
00435 Set_first_wn(region_wn);
00436
00437
00438 REGION_emit(bb_region->Rid(), region_wn, _region_level,
00439 bb_region->Region_num_exits(), bb_region->Region_line_num());
00440 }
00441 }
00442
00443
00444
00445
00446
00447 RVI_EMIT::RVI_EMIT(const RVI *rvi, BOOL lda_only, ALIAS_MANAGER *alias_mgr,
00448 REGION_LEVEL region_level) :
00449 _rvi(rvi), _lda_only(lda_only), _region_stack(rvi->Rvi_ppool())
00450 {
00451
00452 _entry_wn = NULL;
00453 _first_wn = NULL;
00454 _last_wn = NULL;
00455 _alias_mgr = alias_mgr;
00456 _region_level = region_level;
00457
00458
00459 CFG_ITER cfg_iter(Rvi()->Cfg());
00460 BB_NODE *bb;
00461 FOR_ALL_NODE( bb, cfg_iter, Init() ) {
00462
00463 Is_Trace(Rvi()->Tracing(),(TFile,"----- BB%d -----\n",bb->Id()));
00464
00465
00466 if ( bb->Kind() == BB_REGIONSTART ) {
00467 Is_Trace(Rvi()->Tracing(),
00468 (TFile,"RVI_EMIT, Push_region BB%d\n",bb->Id()));
00469 Push_region(bb);
00470 }
00471
00472 if ( bb->Rvi_anns() != NULL ) {
00473 Emit_bb_annotations( bb );
00474 }
00475
00476 Emit_bb( bb );
00477
00478
00479 while ( _region_stack.Elements() > 0 &&
00480 _region_stack.Top()->Region_end() == bb )
00481 {
00482 Is_Trace(Rvi()->Tracing(),(TFile,"RVI_EMIT, Pop_region\n"));
00483 Pop_region();
00484 }
00485 }
00486
00487
00488 Is_True( _region_stack.Elements() == 0,
00489 ("RVI_EMIT::RVI_EMIT: region stack not empty") );
00490
00491
00492
00493 BB_NODE *entry_bb = Rvi()->Cfg()->Find_entry_bb();
00494 if (entry_bb->Kind() == BB_ENTRY) {
00495 if ( Entry_wn() != NULL ) {
00496 WN *block = WN_CreateBlock();
00497 WN_first(block) = First_wn();
00498 WN_last(block) = Last_wn();
00499 WN_Set_Linenum( block, WN_Get_Linenum(Entry_wn()) );
00500
00501 const OPCODE eopc = WN_opcode(Entry_wn());
00502 if ( eopc == OPC_FUNC_ENTRY ) {
00503 WN_func_body(Entry_wn()) = block;
00504 REGION_emit(Rvi()->Cfg()->Rid(), Entry_wn(), _region_level, 1, 0);
00505 } else {
00506 FmtAssert( FALSE, ("RVI_EMIT::RVI_EMIT: Can't handle entry %s",
00507 OPCODE_name(eopc)) );
00508 }
00509 }
00510 } else {
00511 Is_True(entry_bb->Kind() == BB_REGIONSTART,
00512 ("RVI_EMIT::RVI_EMIT, unknown entry kind %s",
00513 entry_bb->Kind_name()));
00514 Set_entry_wn(First_wn());
00515 Is_True(REGION_consistency_check(Entry_wn()),
00516 ("RVI_EMIT::RVI_EMIT, inconsistent region"));
00517 }
00518
00519 }