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
00059
00060
00061
00062 #ifdef USE_PCH
00063 #include "opt_pch.h"
00064 #endif // USE_PCH
00065 #pragma hdrstop
00066
00067
00068 #ifdef _KEEP_RCS_ID
00069 #define opt_rviwn_CXX "opt_rviwn.cxx"
00070 static char *rcs_id = opt_rviwn_CXX"$Revision: 1.11 $";
00071 #endif
00072
00073 #include "defs.h"
00074 #include "errors.h"
00075 #include "erglob.h"
00076 #include "tracing.h"
00077 #include "stab.h"
00078 #include "wn.h"
00079 #include "wn_util.h"
00080 #include "config.h"
00081 #include "cxx_memory.h"
00082
00083 #include "w2op.h"
00084 #include "data_layout.h"
00085
00086 #include "opt_defs.h"
00087 #include "opt_config.h"
00088 #include "opt_base.h"
00089 #include "opt_bb.h"
00090 #include "opt_cfg.h"
00091 #include "opt_alias_mgr.h"
00092 #include "opt_wn.h"
00093 #include "opt_rvilr.h"
00094 #include "opt_rvitab.h"
00095 #include "opt_rviwn.h"
00096 #include "opt_rvi.h"
00097 #include "opt_util.h"
00098 #include "bb_node_set.h"
00099 #include "idx_32_set.h"
00100 #include "opt_cvtl_rule.h"
00101
00102
00103
00104
00105
00106
00107 WN *
00108 RVI_ANN::New_ldid( ALIAS_MANAGER *alias_mgr ) const
00109 {
00110 MTYPE mtype = TY_mtype(ST_type(Preg_st()));
00111 OPCODE load_opc = OPCODE_make_op( OPR_LDID, mtype, mtype );
00112 WN *newldid = WN_CreateLdid( load_opc, Preg(), Preg_st(),
00113 MTYPE_To_TY(mtype) );
00114 alias_mgr->Gen_alias_id(newldid, NULL);
00115 return newldid;
00116 }
00117
00118
00119
00120
00121
00122 void
00123 RVI_ANN::Print( FILE *fp ) const
00124 {
00125 fprintf( fp, "ST:%s Preg:%d Bitpos:%d\n",
00126 ST_name(Preg_st()), Preg(), Bitpos() );
00127 }
00128
00129
00130
00131
00132
00133 RVI_ANN *
00134 RVI_ANN_LIST::Find( const IDX_32 bitpos )
00135 {
00136 RVI_ANN_ITER ann_iter;
00137 RVI_ANN *ann;
00138 FOR_ALL_NODE( ann, ann_iter, Init(this) ) {
00139 if ( bitpos == ann->Bitpos() ) {
00140 return ann;
00141 }
00142 }
00143
00144 return NULL;
00145 }
00146
00147
00148
00149
00150
00151 void
00152 RVI_ANN_LIST::Print( FILE *fp )
00153 {
00154 RVI_ANN_ITER ann_iter;
00155 RVI_ANN *ann;
00156 FOR_ALL_NODE( ann, ann_iter, Init(this) ) {
00157 ann->Print( fp );
00158 }
00159 }
00160
00161
00162
00163
00164
00165 void
00166 RVI::Insert_statement( BB_NODE *bb, WN *wn, RVI_INSERT insert ) const
00167 {
00168 if ( insert == RVI_INS_TOP ) {
00169
00170 if ( bb->Firststmt() != NULL ) {
00171 WN_Set_Linenum( wn, WN_Get_Linenum(bb->Firststmt()) );
00172 }
00173
00174 bb->Prepend_wn_after_labels( wn );
00175 }
00176 else if ( insert == RVI_INS_BEFORE_IREF ) {
00177
00178 Is_True ( bb->Loc_mu_wn() != NULL,
00179 ("RVI::Insert_statement: ins before null iref") );
00180
00181 WN_Set_Linenum( wn, WN_Get_Linenum(bb->Loc_mu_wn()) );
00182 bb->Insert_wn_before( wn, bb->Loc_mu_wn() );
00183 }
00184 else {
00185 WN *last_stmt;
00186
00187 if ( insert == RVI_INS_PRECALL ) {
00188 last_stmt = bb->Hascall() ? bb->Loc_mu_wn() : bb->Laststmt();
00189 }
00190 else if ( insert == RVI_INS_POSTCHI ) {
00191 last_stmt = bb->Loc_mu_wn();
00192 if ( last_stmt == NULL )
00193 last_stmt = bb->Laststmt();
00194 }
00195 else {
00196 Is_True( FALSE,
00197 ("RVI::Insert_statement: bad insert value") );
00198 }
00199
00200 if ( last_stmt != NULL ) {
00201
00202 WN_Set_Linenum( wn, WN_Get_Linenum(last_stmt) );
00203
00204
00205 if ( bb->Hascall() ) {
00206 if ( insert == RVI_INS_PRECALL ) {
00207 bb->Insert_wn_before( wn, last_stmt );
00208 }
00209 else {
00210 bb->Insert_wn_after( wn, last_stmt );
00211 }
00212 }
00213 else if ( OPCODE_is_endsbb(WN_opcode(last_stmt)) ) {
00214
00215
00216 bb->Insert_wn_before( wn, last_stmt );
00217 }
00218 else {
00219
00220 bb->Insert_wn_after( wn, last_stmt );
00221 }
00222 }
00223 else {
00224
00225 bb->Insert_wn_before( wn, NULL );
00226 }
00227 }
00228
00229 if ( Tracing() ) {
00230 const char *msg;
00231 switch ( insert ) {
00232 case RVI_INS_TOP: msg = "at top"; break;
00233 case RVI_INS_BEFORE_IREF: msg = "before iref"; break;
00234 case RVI_INS_PRECALL: msg = "before call"; break;
00235 case RVI_INS_POSTCHI: msg = "after chi"; break;
00236 }
00237
00238 fprintf( TFile, "RVI::Insert_statement: added %s of BB:%d\n",
00239 msg, bb->Id() );
00240 fdump_tree( TFile, wn );
00241 }
00242 }
00243
00244
00245
00246
00247
00248 WN *
00249 RVI_NODE::Create_load( INT32 preg, ALIAS_MANAGER *alias_mgr ) const
00250 {
00251 WN *newload = NULL;
00252 if (Loadwn() != NULL)
00253 newload = WN_COPY_Tree(Loadwn());
00254 else {
00255 OPCODE newldid_opc = OPCODE_make_op(OPR_LDID,
00256 Mtype(),
00257 WN_desc(Storewn()));
00258 newload = WN_CreateLdid( newldid_opc,
00259 WN_store_offset(Storewn()),
00260 WN_st(Storewn()),
00261 WN_ty(Storewn()));
00262 }
00263 if (OPCODE_is_load(WN_opcode(newload))) {
00264 if (Loadwn() != NULL) {
00265 alias_mgr->Dup_tree_alias_id( Loadwn(), newload );
00266 WN_dup_dep_vertex(Loadwn(), newload);
00267 } else
00268 Copy_alias_info(alias_mgr, Storewn(), newload);
00269 alias_mgr->Set_homing_load( newload, TRUE );
00270 }
00271 MTYPE mtype = Mtype();
00272 OPCODE newstore_opc = OPCODE_make_op(OPR_STID,MTYPE_V,mtype);
00273 ST *preg_st = MTYPE_To_PREG( mtype );
00274 WN *pregstore = WN_CreateStid( newstore_opc,
00275 preg, preg_st,
00276 MTYPE_To_TY(mtype),
00277 newload );
00278 alias_mgr->Gen_alias_id(pregstore, NULL);
00279 return pregstore;
00280 }
00281
00282
00283
00284
00285
00286 WN *
00287 RVI_NODE::Create_store( INT32 preg, ALIAS_MANAGER *alias_mgr ) const
00288 {
00289 MTYPE mtype = Mtype();
00290 OPCODE load_opc = OPCODE_make_op( OPR_LDID, mtype, mtype );
00291 ST *preg_st = MTYPE_To_PREG( mtype );
00292 WN *pregload = WN_CreateLdid( load_opc, preg, preg_st,
00293 MTYPE_To_TY(mtype) );
00294 alias_mgr->Gen_alias_id(pregload, NULL);
00295
00296 OPCODE newstore_opc = WN_opcode(Storewn());
00297 WN *varstore = WN_CreateStid( newstore_opc,
00298 WN_store_offset(Storewn()),
00299 WN_st(Storewn()),
00300 WN_ty(Storewn()),
00301 pregload );
00302 Copy_alias_info(alias_mgr, Storewn(), varstore);
00303 WN_dup_dep_vertex(Storewn(), varstore);
00304 alias_mgr->Set_homing_store( varstore, TRUE );
00305
00306 return varstore;
00307 }
00308
00309
00310
00311
00312
00313 void
00314 RVI::Insert_load( RVI_LRBB *lrbb, WN *loadwn, RVI_LR *live_range ) const
00315 {
00316
00317
00318 if ( lrbb->Need_load_here() ) {
00319 if ( ! Redundant_load_top()->MemberP(lrbb->Bb()) ) {
00320 Insert_statement( lrbb->Bb(), loadwn, RVI_INS_TOP );
00321 Redundant_load_top()->Union1D(lrbb->Bb());
00322 }
00323 }
00324 else if ( lrbb->Need_load_pred() || lrbb->Need_load_chi() ) {
00325
00326
00327
00328 BOOL pred_is_entry = FALSE;
00329 BB_LIST_ITER bb_iter;
00330 BB_NODE *pred;
00331 FOR_ALL_ELEM( pred, bb_iter, Init(lrbb->Bb()->Pred()) ) {
00332 if (pred->Kind() == BB_ENTRY ||
00333 pred->Kind() == BB_REGIONSTART) {
00334 pred_is_entry = TRUE;
00335 break;
00336 }
00337 }
00338 if (pred_is_entry) {
00339 if ( ! Redundant_load_top()->MemberP(lrbb->Bb()) ) {
00340 Insert_statement( lrbb->Bb(), loadwn, RVI_INS_TOP );
00341 Redundant_load_top()->Union1D(lrbb->Bb());
00342 }
00343 } else {
00344 BOOL need_copy = FALSE;
00345 FOR_ALL_ELEM( pred, bb_iter, Init(lrbb->Bb()->Pred()) ) {
00346
00347 BOOL pred_in_lr = live_range->Block_set()->MemberP( pred );
00348
00349
00350
00351 if ( pred_in_lr && lrbb->Need_load_chi() ) {
00352
00353 if ( Has_end_chi_list(pred) ) {
00354 const IDX_32_SET *pred_chi = Bb_end_chi_list(pred);
00355 if ( pred_chi != NULL &&
00356 pred_chi->MemberP(live_range->Bitpos()) )
00357 {
00358
00359
00360 pred_in_lr = FALSE;
00361 }
00362 }
00363 }
00364
00365 if ( ! pred_in_lr ) {
00366 if ( ! Redundant_load_bot()->MemberP(pred) ) {
00367 if ( ! need_copy ) {
00368 Insert_statement( pred, loadwn, RVI_INS_POSTCHI );
00369 Redundant_load_bot()->Union1D(pred);
00370 }
00371 else {
00372 WN *cp_wn = WN_COPY_Tree(loadwn);
00373 Alias_Mgr()->Dup_tree_alias_id( loadwn, cp_wn );
00374 WN_dup_dep_vertex(loadwn, cp_wn);
00375 Insert_statement( pred, cp_wn, RVI_INS_POSTCHI );
00376 Redundant_load_bot()->Union1D(pred);
00377 }
00378
00379 need_copy = TRUE;
00380 }
00381 }
00382 }
00383 }
00384 }
00385 else {
00386 FmtAssert( FALSE, ("RVI::Insert_load: no loads needed") );
00387 }
00388 }
00389
00390
00391
00392
00393
00394 void
00395 RVI::Insert_store( RVI_LRBB *lrbb, WN *storewn, RVI_LR *live_range ) const
00396 {
00397 BOOL need_copy = FALSE;
00398
00399
00400
00401
00402
00403 if ( lrbb->Need_store_iref() ) {
00404 if ( ! Redundant_store_iref()->MemberP(lrbb->Bb()) ) {
00405 Insert_statement( lrbb->Bb(), storewn, RVI_INS_BEFORE_IREF );
00406 Redundant_store_iref()->Union1D(lrbb->Bb());
00407 need_copy = TRUE;
00408 }
00409 }
00410
00411
00412
00413 if ( lrbb->Need_store_bot() ) {
00414 BOOL need_store_bot = ! Redundant_store_iref()->MemberP(lrbb->Bb());
00415 if ( ! need_store_bot ) {
00416
00417
00418
00419 if ( lrbb->Bb()->Last_stid_bitpos() == live_range->Bitpos() &&
00420 ! lrbb->Bb()->Last_stid_has_chi() )
00421 {
00422 need_store_bot = TRUE;
00423 }
00424 }
00425
00426 if ( need_store_bot ) {
00427 WN *cp_wn = storewn;
00428 if ( need_copy ) {
00429 cp_wn = WN_COPY_Tree(storewn);
00430 Alias_Mgr()->Dup_tree_alias_id( storewn, cp_wn );
00431 WN_dup_dep_vertex(storewn, cp_wn);
00432 }
00433
00434 Insert_statement( lrbb->Bb(), cp_wn, RVI_INS_PRECALL );
00435 Redundant_store_iref()->Union1D(lrbb->Bb());
00436 }
00437 }
00438 else if ( lrbb->Need_store_succ() ) {
00439 BB_LIST_ITER bb_iter;
00440 BB_NODE *succ;
00441 FOR_ALL_ELEM( succ, bb_iter, Init(lrbb->Bb()->Succ()) ) {
00442
00443 if ( ! live_range->Block_set()->MemberP( succ ) ) {
00444 if ( ! Redundant_store_top()->MemberP(succ) ) {
00445 WN *cp_wn = storewn;
00446 if ( need_copy ) {
00447 cp_wn = WN_COPY_Tree(storewn);
00448 Alias_Mgr()->Dup_tree_alias_id( storewn, cp_wn );
00449 WN_dup_dep_vertex(storewn, cp_wn);
00450 }
00451
00452 Insert_statement( succ, cp_wn, RVI_INS_TOP );
00453 Redundant_store_top()->Union1D(succ);
00454 need_copy = TRUE;
00455 }
00456 }
00457 }
00458 }
00459 else {
00460 FmtAssert( lrbb->Need_store_iref(),
00461 ("RVI::Insert_store: no stores needed") );
00462 }
00463 }
00464
00465
00466
00467
00468
00469
00470 void
00471 RVI::Annotate_load_store( BB_NODE *bb, RVI_NODE *node, INT32 preg )
00472 {
00473
00474 if ( bb->Rvi_anns() == NULL ) {
00475 bb->Set_rvi_anns( CXX_NEW(RVI_ANN_LIST(),Rvi_ppool()) );
00476 }
00477
00478 ST *preg_st = MTYPE_To_PREG( node->Mtype() );
00479 RVI_ANN *rvi_ann = CXX_NEW( RVI_ANN( preg_st, preg, node ),
00480 Rvi_ppool() );
00481 bb->Rvi_anns()->Prepend(rvi_ann);
00482 }
00483
00484
00485
00486
00487
00488
00489 void
00490 RVI::Insert_loads_stores( RVI_LR *live_range, RVI_NODE *node )
00491 {
00492 if ( ! live_range->Replace_anything() ) {
00493 return;
00494 }
00495
00496 FmtAssert( live_range->Preg() != 0,
00497 ("RVI::Insert_loads_stores: no preg for node %d",
00498 node->Bitpos()) );
00499
00500
00501 Clear_redundant();
00502
00503 RVI_LRBB_ITER lrbb_iter;
00504 RVI_LRBB *lrbb;
00505 FOR_ALL_NODE( lrbb, lrbb_iter, Init(live_range->Blocks()) ) {
00506 if ( lrbb->Load_cnt() > 0 || lrbb->Store_cnt() > 0 ) {
00507 Annotate_load_store( lrbb->Bb(), node, live_range->Preg() );
00508 }
00509 if ( lrbb->Need_load() ) {
00510 WN *loadwn = node->Create_load(live_range->Preg(), Alias_Mgr());
00511 Insert_load( lrbb, loadwn, live_range );
00512 }
00513 if ( lrbb->Need_store() ) {
00514 WN *storewn = node->Create_store(live_range->Preg(), Alias_Mgr());
00515 Insert_store( lrbb, storewn, live_range );
00516 }
00517 }
00518 }
00519
00520
00521
00522
00523
00524 inline BOOL
00525 Is_div_handled_constant( INT64 con_val )
00526 {
00527
00528 if ( con_val == ( con_val & ~(con_val-1) ) )
00529 return TRUE;
00530
00531 return FALSE;
00532 }
00533
00534
00535
00536
00537
00538
00539 BOOL
00540 RVI::Is_const_candidate( const WN *parent, const WN *constant, INT whichkid ) const
00541 {
00542 const OPCODE con_opc = WN_opcode(constant);
00543 const OPERATOR con_opr = OPCODE_operator(con_opc);
00544 const OPCODE par_opc = WN_opcode(parent);
00545 const OPERATOR par_opr = OPCODE_operator(par_opc);
00546 const MTYPE par_dtyp = OPCODE_rtype(par_opc);
00547 ST * const stid_st = (par_opr == OPR_STID) ? WN_st(parent) : NULL;
00548
00549 Is_True( con_opr == OPR_INTCONST,
00550 ("RVI::Is_const_candidate: Bad const: %s", OPCODE_name(con_opc)) );
00551 const INT64 con_val = WN_const_val(constant);
00552
00553 #ifdef TARG_MIPS
00554 if (con_val == 0)
00555 return FALSE;
00556 #endif
00557
00558 return !Can_Be_Immediate(par_opr, con_val, par_dtyp, whichkid, stid_st);
00559 }
00560
00561
00562
00563
00564
00565
00566 BOOL
00567 RVI::Is_lda_candidate( const WN *parent, const WN *lda, INT whichkid ) const
00568 {
00569 const OPCODE lda_opc = WN_opcode(lda);
00570 const OPERATOR lda_opr = OPCODE_operator(lda_opc);
00571 const OPCODE par_opc = WN_opcode(parent);
00572 const OPERATOR par_opr = OPCODE_operator(par_opc);
00573
00574 Is_True( lda_opr == OPR_LDA,
00575 ("RVI::Is_lda_candidate: Bad lda: %s", OPCODE_name(lda_opc)) );
00576 const WN_OFFSET lda_offset = WN_lda_offset(lda);
00577 ST *lda_st = WN_st(lda);
00578
00579 switch ( par_opr ) {
00580 case OPR_ILOAD:
00581 case OPR_MLOAD:
00582
00583 if ( whichkid == 0 ) {
00584 return !Uses_Small_Offset( lda_st, lda_offset );
00585 }
00586 return TRUE;
00587
00588 case OPR_ISTORE:
00589 case OPR_MSTORE:
00590
00591
00592 if ( whichkid == 1 ) {
00593 WN *rhs = WN_kid0(parent);
00594 return (!Uses_Small_Offset( lda_st, lda_offset ) &&
00595 !(WN_operator(rhs) == OPR_LDID &&
00596 ST_class(WN_st(rhs)) == CLASS_PREG &&
00597 Preg_Is_Dedicated(WN_offset(rhs))));
00598 }
00599 return TRUE;
00600
00601 case OPR_ILOADX:
00602 case OPR_ISTOREX:
00603 return FALSE;
00604
00605 case OPR_CALL:
00606 case OPR_ICALL:
00607 case OPR_INTRINSIC_CALL:
00608 case OPR_PARM:
00609
00610
00611
00612 return !Uses_Small_Offset( lda_st, lda_offset );
00613
00614 case OPR_PICCALL:
00615
00616
00617 if ( whichkid == WN_kid_count(parent)-1 ) {
00618 if ( Enable_GOT_Call_Conversion ) {
00619
00620 return TRUE;
00621 }
00622 else {
00623
00624
00625 if ((Gen_PIC_Call_Shared || Gen_PIC_Shared) &&
00626 !ST_visible_outside_dso(lda_st) )
00627 {
00628 return TRUE;
00629 }
00630 }
00631
00632 return FALSE;
00633 }
00634 else {
00635
00636
00637
00638
00639
00640 return !Uses_Small_Offset( lda_st, lda_offset );
00641 }
00642
00643 case OPR_STID:
00644
00645
00646
00647 if ( ST_class(WN_st(parent)) == CLASS_PREG &&
00648 Uses_Small_Offset( lda_st, lda_offset ) )
00649 {
00650
00651 return FALSE;
00652 }
00653 return TRUE;
00654
00655 default:
00656 return TRUE;
00657 }
00658 }
00659
00660
00661
00662
00663
00664
00665 static BOOL
00666 Need_cvtl_for_store_to_preg( MTYPE store_type, MTYPE rhs_type,
00667 MTYPE preg_type, WN *rhs )
00668 {
00669
00670 if ( MTYPE_size_min(store_type) < MTYPE_size_min(preg_type) &&
00671 MTYPE_size_min(rhs_type) > MTYPE_size_min(store_type) )
00672 {
00673
00674 OPCODE new_cvtl_opc = OPCODE_make_op(OPR_CVTL, preg_type, MTYPE_V);
00675 if ( WN_opcode(rhs) == new_cvtl_opc &&
00676 WN_cvtl_bits(rhs) == MTYPE_size_min(store_type) )
00677 {
00678
00679
00680 return FALSE;
00681 }
00682 return TRUE;
00683 }
00684
00685 return FALSE;
00686 }
00687
00688
00689
00690
00691
00692
00693 void
00694 RVI::Store_to_preg_cvtl(WN *store_wn, ST* preg_st,
00695 TY_IDX preg_ty, PREG_NUM preg_num) const
00696 {
00697 OPCODE store_opc = WN_opcode(store_wn);
00698 MTYPE store_type = OPCODE_desc(store_opc);
00699 MTYPE preg_type = TY_mtype(preg_ty);
00700 WN *rhs = WN_kid0(store_wn);
00701 MTYPE rhs_type = Actual_result_type(rhs);
00702
00703 if (WN_operator(rhs) == OPR_INTCONST) {
00704 MTYPE new_type = Adjust_signed_type(preg_type,
00705 MTYPE_size_min(store_type), rhs);
00706 if (new_type) rhs_type = new_type;
00707 }
00708
00709
00710 if ( Need_cvtl_for_store_to_preg(store_type,rhs_type,preg_type,rhs) ){
00711 OPCODE cvtl_opc = OPCODE_make_op( OPR_CVTL, preg_type, MTYPE_V );
00712 WN *new_val = WN_CreateCvtl( cvtl_opc, MTYPE_size_min(store_type),
00713 rhs );
00714 WN_kid0(store_wn) = new_val;
00715 }
00716 else if (MTYPE_size_min(store_type) <= MTYPE_size_min(rhs_type)){
00717 INT cvt_kind;
00718 OPCODE opc;
00719 cvt_kind = Need_type_conversion(rhs_type, store_type, &opc);
00720 if (cvt_kind == NEED_CVT) {
00721 WN *new_val = WN_CreateExp1( opc, rhs );
00722 WN_kid0(store_wn) = new_val;
00723 }
00724 }
00725
00726 WN_store_offset(store_wn) = preg_num;
00727 WN_st_idx(store_wn) = ST_st_idx(preg_st);
00728 WN_set_ty( store_wn, preg_ty );
00729
00730 Alias_Mgr()->Gen_alias_id(store_wn, NULL);
00731 }
00732
00733
00734
00735
00736
00737
00738
00739
00740 void
00741 RVI::Store_to_preg_and_mem( BB_NODE *bb, WN *store_wn,
00742 ST* preg_st, TY_IDX preg_ty, PREG_NUM preg_num ) const
00743 {
00744 OPCODE store_opc = WN_opcode(store_wn);
00745 MTYPE store_type = OPCODE_desc(store_opc);
00746 MTYPE preg_type = TY_mtype(preg_ty);
00747 WN *rhs = WN_kid0(store_wn);
00748 MTYPE rhs_type = Actual_result_type(rhs);
00749
00750 if (WN_operator(rhs) == OPR_INTCONST) {
00751 MTYPE new_type = Adjust_signed_type(preg_type,
00752 MTYPE_size_min(store_type), rhs);
00753 if (new_type) rhs_type = new_type;
00754 }
00755
00756
00757 if ( Need_cvtl_for_store_to_preg(store_type,rhs_type,preg_type,rhs) ){
00758 OPCODE cvtl_opc = OPCODE_make_op( OPR_CVTL, preg_type, MTYPE_V );
00759 WN *new_val = WN_CreateCvtl( cvtl_opc, MTYPE_size_min(store_type),
00760 rhs );
00761 WN_kid0(store_wn) = new_val;
00762 }
00763 else if (MTYPE_size_min(store_type) <= MTYPE_size_min(rhs_type)){
00764 INT cvt_kind;
00765 OPCODE opc;
00766 cvt_kind = Need_type_conversion(rhs_type, store_type, &opc);
00767 if (cvt_kind == NEED_CVT) {
00768 WN *new_val = WN_CreateExp1( opc, rhs );
00769 WN_kid0(store_wn) = new_val;
00770 }
00771 }
00772
00773
00774 WN *new_store = WN_CreateStid( WN_opcode(store_wn),
00775 preg_num, preg_st, preg_ty, WN_kid0(store_wn) );
00776 Alias_Mgr()->Gen_alias_id( new_store, NULL );
00777 WN_Set_Linenum( new_store, WN_Get_Linenum(store_wn) );
00778
00779
00780 const OPCODE ldid_opc = OPCODE_make_op(OPR_LDID,preg_type,preg_type);
00781 WN *new_ldid = WN_CreateLdid( ldid_opc, preg_num, preg_st, preg_ty );
00782 Alias_Mgr()->Gen_alias_id( new_ldid, NULL );
00783 WN_kid0(store_wn) = new_ldid;
00784 Alias_Mgr()->Set_homing_store( store_wn, TRUE );
00785
00786
00787 bb->Insert_wn_before( new_store, store_wn );
00788 }
00789
00790
00791
00792
00793
00794
00795
00796
00797 WN *
00798 RVI::Load_from_preg_cvtl( WN *wn, OPCODE load_opc ) const
00799 {
00800 const OPCODE opc = WN_opcode(wn);
00801 if ( opc == load_opc )
00802 return wn;
00803
00804 if ( Tracing() ) {
00805 fprintf( TFile, "RVI::Load_from_preg_cvtl: converting\n" );
00806 fdump_tree( TFile, wn );
00807 }
00808
00809
00810
00811 WN_set_opcode(wn, load_opc);
00812
00813
00814 WN *convert1_wn = WN_Type_Conversion( wn, OPCODE_desc(opc) );
00815
00816
00817 WN *convert2_wn = WN_Type_Conversion( convert1_wn, OPCODE_rtype(opc));
00818
00819 if ( Tracing() ) {
00820 fprintf( TFile, " converted value\n" );
00821 fdump_tree( TFile, convert2_wn );
00822 }
00823
00824 return convert2_wn;
00825 }
00826
00827
00828
00829
00830
00831
00832
00833
00834 static BOOL
00835 WN_is_store_of_ded_reg( const WN *wn )
00836 {
00837 const OPERATOR opr = WN_operator(wn);
00838
00839 if ( opr == OPR_STID || opr == OPR_ISTORE || opr == OPR_ISTOREX )
00840 {
00841 WN *val = WN_kid0(wn);
00842 const OPERATOR val_opr = WN_operator(val);
00843 if ( val_opr == OPR_LDID ) {
00844 ST *val_st = WN_st(val);
00845 if ( ST_class(val_st) == CLASS_PREG &&
00846 Preg_Is_Dedicated(WN_offset(val)) )
00847 {
00848 return TRUE;
00849 }
00850 }
00851 }
00852
00853
00854 return FALSE;
00855 }
00856
00857 inline BOOL
00858 WN_is_store_to_preg( const WN *wn )
00859 {
00860 const OPERATOR opr = WN_operator(wn);
00861
00862 if ( opr == OPR_STID ) {
00863 if ( ST_class(WN_st(wn)) == CLASS_PREG ) {
00864 return TRUE;
00865 }
00866 }
00867
00868
00869 return FALSE;
00870 }
00871
00872 static void
00873 Replace_store_of_ded_reg( BB_NODE *bb,
00874 WN *wn, WN *insert_ded_reg_ref_before,
00875 ALIAS_MANAGER *alias_mgr,
00876 BOOL trace )
00877 {
00878 WN *ded_ldid = WN_kid0(wn);
00879 ST *ded_st = WN_st(ded_ldid);
00880 MTYPE reg_type = TY_mtype(ST_type(ded_st));
00881 PREG_NUM pregnum = Create_Preg( reg_type, NULL);
00882
00883 if ( trace ) {
00884 fprintf( TFile, "Replace_store_of_ded_reg: BB:%d replacing:\n",
00885 bb->Id() );
00886 fdump_tree( TFile, wn );
00887 }
00888
00889
00890 WN *new_ldid = WN_LdidPreg( reg_type, pregnum );
00891 alias_mgr->Gen_alias_id( new_ldid, NULL );
00892 WN_kid0(wn) = new_ldid;
00893
00894
00895 WN *new_store = WN_StidIntoPreg( reg_type, pregnum, ded_st, ded_ldid);
00896 alias_mgr->Gen_alias_id( new_store, NULL );
00897
00898
00899 bb->Insert_wn_before( new_store, insert_ded_reg_ref_before );
00900
00901 if ( trace ) {
00902 fprintf( TFile, " replaced with:\n" );
00903 fdump_tree( TFile, new_store );
00904 fdump_tree( TFile, wn );
00905 }
00906 }
00907
00908
00909 void
00910 RVI::Set_callrel() const
00911 {
00912
00913
00914
00915
00916
00917 CFG_ITER cfg_iter(Cfg());
00918 BB_NODE *bb;
00919 WN *insert_ded_preg_ref_before = NULL;
00920
00921 FOR_ALL_NODE( bb, cfg_iter, Init() ) {
00922
00923 if (!bb->Callrel() && bb->Kind() == BB_ENTRY) {
00924
00925
00926
00927
00928 BB_NODE *succ;
00929 BB_LIST_ITER bb_succ_iter;
00930 FOR_ALL_ELEM( succ, bb_succ_iter, Init(bb->Succ()) ) {
00931 succ->Set_callrel();
00932 }
00933 }
00934 }
00935 }
00936
00937
00938 void
00939 RVI::Copy_dedicated_regs_to_pregs( void ) const
00940 {
00941
00942
00943 CFG_ITER cfg_iter(Cfg());
00944 BB_NODE *bb;
00945 WN *insert_ded_preg_ref_before = NULL;
00946
00947 FOR_ALL_NODE( bb, cfg_iter, Init() ) {
00948
00949
00950 if ( bb->Callrel() ) {
00951
00952 WN *wn;
00953 for ( wn = bb->Firststmt(); wn != NULL; wn = WN_next(wn) ) {
00954 if ( OPCODE_is_store(WN_opcode(wn)) )
00955 break;
00956 }
00957
00958
00959 if ( wn != NULL && WN_is_store_of_ded_reg(wn) ) {
00960 if ( ! WN_is_store_to_preg( wn ) ) {
00961 Replace_store_of_ded_reg( bb, wn, wn, Alias_Mgr(), Tracing() );
00962 insert_ded_preg_ref_before = wn;
00963 }
00964 }
00965 if (insert_ded_preg_ref_before != NULL)
00966 {
00967
00968
00969
00970 wn = WN_next(wn);
00971 if ( wn != NULL && WN_is_store_of_ded_reg(wn) ) {
00972 if ( ! WN_is_store_to_preg( wn ) ) {
00973 Replace_store_of_ded_reg( bb, wn, insert_ded_preg_ref_before,
00974 Alias_Mgr(), Tracing() );
00975 insert_ded_preg_ref_before = NULL;
00976 }
00977 }
00978 }
00979 }
00980 else if ( bb->Kind() == BB_ENTRY ) {
00981
00982
00983
00984
00985 BB_NODE *succ;
00986 BB_LIST_ITER bb_succ_iter;
00987 FOR_ALL_ELEM( succ, bb_succ_iter, Init(bb->Succ()) ) {
00988 succ->Set_callrel();
00989 }
00990 }
00991 }
00992 }
00993