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 #define opt_lpre_CXX "opt_lpre.cxx"
00069
00070 #include "defs.h"
00071 #include "cxx_memory.h"
00072 #include "data_layout.h"
00073 #include "w2op.h"
00074 #include "wn_core.h"
00075 #include "config.h"
00076
00077 #include "opt_base.h"
00078 #include "opt_bb.h"
00079 #include "opt_cfg.h"
00080 #include "opt_estr.h"
00081 #include "opt_etable.h"
00082 #include "opt_efinalize.h"
00083 #include "opt_mu_chi.h"
00084 #include "opt_htable.h"
00085 #include "opt_main.h"
00086 #include "opt_ssa.h"
00087 #include "opt_sys.h"
00088 #include "opt_util.h"
00089 #include "tracing.h"
00090 #include "opt_lftr2.h"
00091 #include "config_targ.h"
00092
00093
00094
00095
00096
00097
00098 void
00099 ETABLE::LPRE_bottom_up_stmt(STMTREP *stmt)
00100 {
00101 const OPERATOR stmt_opr = OPCODE_operator(stmt->Op());
00102
00103 Is_Trace(Tracing(),
00104 (TFile, "----- stmt: %s -----\n", OPCODE_name(stmt->Op())));
00105 Is_Trace_cmd(Tracing(),stmt->Print(TFile));
00106
00107 stmt->Set_stmt_id(Cfg()->Get_stmt_id());
00108
00109
00110
00111 CODEREP *rhs = stmt->Rhs();
00112 CODEREP *lhs = stmt->Lhs();
00113
00114 if (OPCODE_is_fake(stmt->Op())) {
00115 for (INT32 i = 0; i < rhs->Kid_count(); i++) {
00116 New_temp_id();
00117 LPRE_bottom_up_cr(stmt, i, rhs->Opnd(i), FALSE, 0, rhs, i);
00118 }
00119 } else if (rhs != NULL) {
00120 New_temp_id();
00121 LPRE_bottom_up_cr(stmt, 0, rhs, FALSE, 0, lhs, 0);
00122 }
00123 if (stmt->Lhs()) {
00124 Is_Trace(Tracing(),(TFile,"Lhs\n"));
00125 New_temp_id();
00126 LPRE_bottom_up_cr(stmt, 1, stmt->Lhs(), OPCODE_is_store(stmt->Op()), 0, NULL, 0);
00127 }
00128 }
00129
00130
00131
00132
00133 void
00134 ETABLE::LPRE_bottom_up_cr(STMTREP *stmt, INT stmt_kid_num, CODEREP *cr,
00135 BOOL is_store, UINT depth, CODEREP *parent, INT whichkid)
00136 {
00137 Is_True(cr != NULL,("ETABLE::LPRE_bottom_up_cr, null CODEREP"));
00138
00139 Is_Trace(Tracing(),(TFile, "----- cr -----\n"));
00140 Is_Trace_cmd(Tracing(),cr->Print(2,TFile));
00141
00142 switch (cr->Kind()) {
00143
00144
00145 case CK_CONST:
00146 if ( LPRE_do_consts() &&
00147 cr->Is_rvi_const_candidate(parent, whichkid, Opt_stab()) )
00148 Append_real_occurrence(cr, stmt, stmt_kid_num, depth, FALSE);
00149 break;
00150 case CK_RCONST:
00151 #ifdef TARG_X8664 // bug 11268: need to keep the real and imag halves together
00152 if (cr->Dtyp() == MTYPE_C4 && parent && parent->Kind() == CK_IVAR &&
00153 parent->Opr() == OPR_PARM)
00154 break;
00155 #endif
00156 if ( LPRE_do_consts() ) {
00157 #ifdef TARG_NVISA
00158
00159 if (!cr->Is_rvi_const_candidate(parent, whichkid, Opt_stab()))
00160 break;
00161 #endif
00162 Append_real_occurrence(cr, stmt, stmt_kid_num, depth, FALSE);
00163 }
00164 break;
00165 case CK_LDA:
00166 if ( LPRE_do_consts() && ! cr->Is_flag_set(CF_LDA_LABEL) &&
00167 cr->Is_rvi_lda_candidate(parent, whichkid, Opt_stab()) )
00168 Append_real_occurrence(cr, stmt, stmt_kid_num, depth, FALSE);
00169 break;
00170
00171 case CK_VAR:
00172
00173 #ifdef TARG_X8664 // bug 11268: need to keep the real and imag halves together
00174 if (cr->Dtyp() == MTYPE_C4 && parent && parent->Kind() == CK_IVAR &&
00175 parent->Opr() == OPR_PARM)
00176 break;
00177 #endif
00178 if ( LPRE_do_loads() &&
00179 !cr->Is_var_volatile() &&
00180
00181 !Opt_stab()->Aux_stab_entry(cr->Aux_id())->No_register() &&
00182 ST_class( Opt_stab()->St(cr->Aux_id()) ) != CLASS_PREG )
00183 {
00184 #ifdef TARG_NVISA
00185 if (Tracing())
00186 Opt_stab()->St(cr->Aux_id())->Print(TFile);
00187 if (!WOPT_Enable_Const_Var_PRE
00188 && ST_is_const_var( Opt_stab()->St(cr->Aux_id())))
00189 {
00190 Is_Trace(Tracing(),(TFile, "don't do lpre on const_var symbol\n"));
00191 } else
00192 #endif
00193 Insert_real_occurrence(cr, stmt, stmt_kid_num, depth, is_store, TRUE);
00194 }
00195 break;
00196
00197 case CK_IVAR:
00198
00199 #ifdef Is_True_On
00200 if (cr->Ilod_base() != NULL && cr->Istr_base() != NULL &&
00201 cr->Ilod_base() != cr->Istr_base())
00202 Warn_todo("CODEREP ilod_base != istr_base.");
00203 if (cr->Opr() == OPR_ILOADX)
00204 Warn_todo("ETABLE::Bottom_up_cr: Indexed load.");
00205 #endif
00206
00207
00208 if (cr->Opr() == OPR_PARM && (cr->Offset() & WN_PARM_DUMMY))
00209 break;
00210
00211 LPRE_bottom_up_cr(stmt, stmt_kid_num,
00212 is_store ? cr->Istr_base() : cr->Ilod_base(),
00213 FALSE, ( depth + 1 ), cr, 0);
00214 if ( cr->Opr() == OPR_MLOAD ) {
00215 LPRE_bottom_up_cr(stmt, stmt_kid_num,
00216 cr->Mload_size() ?
00217 cr->Mload_size() : cr->Mstore_size(),
00218 FALSE, ( depth + 1 ), cr, 1);
00219 }
00220 else if (cr->Opr() == OPR_ILOADX) {
00221 LPRE_bottom_up_cr(stmt, stmt_kid_num, cr->Index(),
00222 FALSE, ( depth + 1 ), cr, 1);
00223 }
00224 break;
00225
00226 case CK_OP:
00227 {
00228 Is_True(cr->Opr() != OPR_ARRAY,
00229 ("ETABLE::LPRE_bottom_up_cr: reach an OPR_ARRAY node,"
00230 "this is a bug in lowering process"));
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 if (cr->Temp_id() == Cur_temp_id())
00243 if (cr->Is_lcse() && (cr->Max_depth() >= depth ||
00244 cr->Max_depth() == 255))
00245 break;
00246 else
00247 cr->Set_is_lcse();
00248 else {
00249 cr->Set_temp_id(Cur_temp_id());
00250 cr->Reset_is_lcse();
00251 cr->Set_max_depth(depth);
00252 }
00253
00254
00255 if (cr->Max_depth() < depth)
00256 cr->Set_max_depth( ( depth <= 255 ) ? depth : 255 );
00257
00258 for (INT32 i=0; i<cr->Kid_count(); i++) {
00259 #ifdef KEY // bug 12471: __builtin_expect's first kid must be constant
00260 if (cr->Opr() == OPR_INTRINSIC_OP && cr->Intrinsic() == INTRN_EXPECT &&
00261 i == 1)
00262 continue;
00263 #endif
00264 LPRE_bottom_up_cr(stmt, stmt_kid_num, cr->Opnd(i), FALSE, (depth+1), cr, i);
00265 }
00266 break;
00267 }
00268 default:
00269 Is_True(0,("ETABLE::Bottom_up_cr(), unexpected kind 0x%x",cr->Kind()));
00270 break;
00271 }
00272 }
00273
00274 void
00275 EXP_WORKLST::Remove_if_saved_to_preg(ETABLE *etable)
00276 {
00277 Is_True(etable->Pre_kind() == PK_LPRE,
00278 ("EXP_WORKLST::Remove_if_saved_to_preg: not called from LPRE"));
00279
00280 EXP_OCCURS *exp_occ, *prev_occ = NULL, *next_occ;
00281 EXP_OCCURS_ITER exp_occ_iter;
00282 exp_occ_iter.Init(Real_occurs().Head());
00283 for (exp_occ = exp_occ_iter.First(); !exp_occ_iter.Is_Empty();
00284 exp_occ = next_occ) {
00285 next_occ = exp_occ_iter.Next();
00286 STMTREP *stmt = exp_occ->Stmt();
00287 if (stmt->Is_saved_RHS() && Exp() == stmt->Rhs()) {
00288 Is_True(stmt->Lhs()->Kind() == CK_VAR &&
00289 ST_class(etable->Opt_stab()->St(stmt->Lhs()->Aux_id())) == CLASS_PREG,
00290 ("EXP_WORKLST::Remove_if_saved_to_preg: Lhs of saved RHS is not a preg"));
00291 etable->Add_to_occ_freelist(exp_occ);
00292 Real_occurs().Remove(prev_occ, exp_occ);
00293 } else
00294 prev_occ = exp_occ;
00295 }
00296 }
00297
00298
00299 void
00300 ETABLE::Perform_LPRE_optimization(void)
00301 {
00302
00303
00304
00305 _str_red = CXX_NEW(STR_RED(Cfg(), Htable(), _etable_pool, _tracing),
00306 _etable_pool);
00307 _lftr = CXX_NEW(LFTR(this, Htable(), Cfg(), LFTR_HASH_SIZE), _etable_pool);
00308
00309
00310 if (WOPT_Enable_Hoisting)
00311 _exp_hoisting = New_EXP_HOISTING(this, _etable_pool);
00312
00313
00314 INT32 Exc_sr_cands_phase = 0;
00315 INT32 Finalize_phase = 0;
00316 INT32 Phi_placement_phase = 0;
00317 INT32 Iterator_phase = 0;
00318 INT32 Exp_renaming_phase = 0;
00319 INT32 Downsafe_prop_phase = 0;
00320 INT32 Phi_liveness_phase = 0;
00321 INT32 Avail_insert_phase = 0;
00322 INT32 Ssa_min_phase = 0;
00323 INT32 Hoist_phase = 0;
00324 INT32 Save_reload_phase = 0;
00325
00326
00327 Cfg()->Dpo_vec();
00328
00329 Cfg()->Reset_stmt_id();
00330
00331 SET_OPT_PHASE("LPRE: Build initial occurrence lists");
00332
00333
00334 if (Get_Trace(TKIND_ALLOC, TP_WOPT1)) {
00335 MEM_Tracing_Enable();
00336 }
00337
00338 Init_worklst();
00339 INT first_rank_e_num = _cur_e_num;
00340 INT bb_cnt = 0, edge_cnt = 0;
00341
00342 #ifdef Is_True_On
00343 CFG_ITER cfg_iter;
00344 BB_NODE *bb;
00345 FOR_ALL_ELEM(bb, cfg_iter, Init(Cfg())) {
00346 bb_cnt++;
00347 edge_cnt += bb->Succ()->Len();
00348 }
00349 #endif
00350
00351 EXP_WORKLST *cur_worklst;
00352 # ifdef KEY
00353 INT32 cur_worklst_idx = 0;
00354 # else
00355 INT32 cur_worklst_idx = -1;
00356 # endif
00357 INT total_phi_count = 0;
00358 INT total_opt_ssa_count = 0;
00359 INT total_dense_ssa_count = 0;
00360 INT orig_coderep_id_cnt = Htable()->Coderep_id_cnt();
00361 EXP_WORKLST_ITER2 worklst_iter(Exp_worklst(), Urgent_worklst());
00362 BOOL use_feedback = WOPT_Enable_Feedback_LPRE;
00363
00364 FOR_ALL_NODE(cur_worklst, worklst_iter, Init()) {
00365
00366 cur_worklst_idx++;
00367 if (WOPT_Enable_Load_PRE_Limit != -1 &&
00368 cur_worklst_idx > WOPT_Enable_Load_PRE_Limit) {
00369 DevWarn("LPRE: skip LPRE for variable with v_num > %d\n",
00370 WOPT_Enable_Load_PRE_Limit);
00371 break;
00372 }
00373
00374 OPT_POOL_Push(Per_expr_pool(), -1);
00375
00376 Is_Trace(Tracing(),
00377 (TFile, "processing %dth expression\n", cur_worklst_idx));
00378 Is_Trace_cmd(Tracing(),cur_worklst->Exp()->Print(0,TFile));
00379 Is_Trace_cmd(Tracing(),cur_worklst->Print(TFile));
00380
00381
00382
00383 Per_worklst_cleanup(cur_worklst);
00384 _str_red->Perform_per_expr_cleanup();
00385
00386
00387 cur_worklst->Set_exclude_sr_cand();
00388
00389 #if defined(TARG_NVISA)
00390 if (cur_worklst->Has_unequal_sizes()) {
00391 Is_Trace(Tracing(), (TFile, "Skipping, different sizes of loads"));
00392 cur_worklst->Remove_occurs(this);
00393 continue;
00394 }
00395 #endif
00396
00397
00398 if (cur_worklst->Exp()->Kind() == CK_CONST) {
00399 const INT64 scon_val = cur_worklst->Exp()->Const_val();
00400 const UINT64 ucon_val = scon_val;
00401 if ( (scon_val >= -32768 && scon_val <= 32767) ||
00402 (ucon_val <= 0xffff) ) {
00403 cur_worklst->Remove_if_saved_to_preg(this);
00404 }
00405 }
00406
00407
00408 SET_OPT_REPEAT_PHASE(Phi_placement_phase, "LPRE: Var phi placement");
00409 if (cur_worklst->Real_occurs().Head() != NULL &&
00410 cur_worklst->Insert_exp_phi(this)) {
00411
00412
00413 SET_OPT_REPEAT_PHASE(Iterator_phase, "LPRE: Iterator");
00414 EXP_ALL_OCCURS_ITER *exp_occ_iter = (EXP_ALL_OCCURS_ITER *)
00415 CXX_NEW(EXP_ALL_OCCURS_ITER(cur_worklst,this,Lftr()), Per_expr_pool());
00416 cur_worklst->Set_iterator(exp_occ_iter);
00417
00418 SET_OPT_REPEAT_PHASE(Exp_renaming_phase, "LPRE: Var version renaming");
00419 cur_worklst->Rename_expression(this);
00420
00421 if (use_feedback) {
00422
00423 cur_worklst->Save_flags();
00424
00425 SET_OPT_REPEAT_PHASE(Downsafe_prop_phase, "LPRE: Var anticipation");
00426 cur_worklst->Propagate_downsafe(this);
00427
00428 OPT_POOL_Push(Etable_local_pool(), -1);
00429
00430 SET_OPT_REPEAT_PHASE(Avail_insert_phase,
00431 "LPRE: Var availability/insertion");
00432 cur_worklst->Compute_forward_attributes(this, TRUE );
00433
00434 SET_OPT_REPEAT_PHASE(Save_reload_phase, "LPRE: Compute var save/reload");
00435 cur_worklst->Compute_save_delete(Htable(), this, NULL);
00436
00437 cur_worklst->Estimate_cost(this, PK_LPRE);
00438
00439
00440 OPT_POOL_Pop(Etable_local_pool(), -1);
00441 }
00442
00443
00444
00445
00446 SET_OPT_REPEAT_PHASE(Downsafe_prop_phase, "LPRE: Var anticipation");
00447 if (cur_worklst->Propagate_downsafe(this)) {
00448
00449 OPT_POOL_Push(Etable_local_pool(), -1);
00450
00451 SET_OPT_REPEAT_PHASE(Avail_insert_phase,
00452 "LPRE: Var availability/insertion");
00453 cur_worklst->Compute_forward_attributes(this);
00454
00455 if (!WOPT_Enable_SSA_Minimization) {
00456
00457 OPT_POOL_Pop(Etable_local_pool(), -1);
00458 }
00459
00460 if (WOPT_Enable_Hoisting) {
00461 SET_OPT_REPEAT_PHASE(Hoist_phase, "LPRE: Var hoisting.");
00462 cur_worklst->Hoist_expression(Exp_hoisting());
00463 }
00464
00465 SET_OPT_REPEAT_PHASE(Save_reload_phase, "LPRE: Compute var save/reload");
00466 cur_worklst->Compute_save_delete(Htable(), this, NULL);
00467
00468 if (WOPT_Enable_SSA_Minimization) {
00469 SET_OPT_REPEAT_PHASE(Ssa_min_phase, "LPRE: SSA minimization");
00470 cur_worklst->Minimize_temp_ssa(this, Tracing());
00471
00472 OPT_POOL_Pop(Etable_local_pool(), -1);
00473 }
00474
00475 SET_OPT_REPEAT_PHASE(Finalize_phase, "LPRE: CO Var save/reload");
00476 cur_worklst->Generate_save_reload(this);
00477
00478 #ifdef Is_True_On
00479 cur_worklst->Verify();
00480 #endif
00481 }
00482
00483 Opt_tlog( "LPRE", 0,
00484 "%d-th expression: Inserts=%d, Saves=%d, Reloads=%d, Temp phis=%d, Hoisted=%d",
00485 cur_worklst_idx,
00486 cur_worklst->Insert_count(),
00487 cur_worklst->Save_count(),
00488 cur_worklst->Reload_count(),
00489 cur_worklst->Temp_phi_count(),
00490 cur_worklst->Hoisted_count());
00491
00492 #ifdef Is_True_On
00493
00494
00495
00496 Opt_tlog( "LPRE", 0,
00497 "%d-th variable: Phis=%d(%d%%), Optimistic_SSA=%d(%d%%), Dense_SSA=%d(%d%%)",
00498 cur_worklst_idx,
00499 cur_worklst->Phi_count(),
00500 cur_worklst->Phi_count() * 100 / bb_cnt,
00501 cur_worklst->Optimistic_ssa_count(),
00502 cur_worklst->Optimistic_ssa_count() * 100 / (bb_cnt+edge_cnt),
00503 cur_worklst->Dense_ssa_count(),
00504 cur_worklst->Dense_ssa_count() * 100 / (bb_cnt+edge_cnt));
00505
00506 total_phi_count += cur_worklst->Phi_count();
00507 total_opt_ssa_count += cur_worklst->Optimistic_ssa_count();
00508 total_dense_ssa_count += cur_worklst->Dense_ssa_count();
00509 #endif
00510
00511 exp_occ_iter->Remove_iter();
00512 cur_worklst->Set_iterator(NULL);
00513
00514 }
00515
00516 cur_worklst->Remove_occurs(this);
00517 OPT_POOL_Pop(Per_expr_pool(), -1);
00518
00519 if (WOPT_Enable_Verify >= 4) {
00520 Is_True(_comp_unit->Verify_CODEMAP(), ("CODEMAP corrupted."));
00521 _comp_unit->Verify_version();
00522 }
00523 }
00524
00525 #ifdef Is_True_On
00526 Opt_tlog("LPRE_PU_info", 0,
00527 "CFG nodes=%d, edges=%d, nodes+edges=%d, init_enum=%d, final_enum=%d",
00528 bb_cnt,
00529 edge_cnt,
00530 bb_cnt + edge_cnt,
00531 first_rank_e_num,
00532 _cur_e_num);
00533
00534 if (_cur_e_num > 0) {
00535 total_phi_count /= _cur_e_num;
00536 total_opt_ssa_count /= _cur_e_num;
00537 total_dense_ssa_count /= _cur_e_num;
00538 }
00539
00540 Opt_tlog("LPRE_PU_info", 0,
00541 "PU Average: Phis=%d(%d%%), Optimistic_SSA=%d(%d%%), Dense_SSA=%d(%d%%)",
00542 total_phi_count,
00543 total_phi_count * 100 / bb_cnt,
00544 total_opt_ssa_count,
00545 total_opt_ssa_count * 100 / (bb_cnt+edge_cnt),
00546 total_dense_ssa_count,
00547 total_dense_ssa_count * 100 / (bb_cnt+edge_cnt));
00548 #endif
00549
00550 if (Tracing()) {
00551 fprintf(TFile, "%sAfter LPRE\n%s", DBar, DBar);
00552 fprintf(TFile, "Statistics (all expressions): Insert Count %d, "
00553 "Save Count %d, Reload Count %d, Temp Phi Count %d, Hoisted Count %d\n",
00554 _num_inserted_saves, _num_cse_saves, _num_cse_reloads,
00555 _num_temp_phis, _num_hoisted);
00556 fprintf(TFile, "Coderep Statistics (entire PU): previous count: %d new count: %d\n",
00557 orig_coderep_id_cnt, Htable()->Coderep_id_cnt());
00558 fprintf(TFile, " Expr nodes changed to temps without rehashing: %d\n",
00559 _num_temp_owners);
00560 Cfg()->Print(TFile);
00561 if (Get_Trace(TKIND_ALLOC, TP_WOPT1)) {
00562 MEM_Trace();
00563 }
00564 }
00565
00566 CXX_DELETE(_str_red,_etable_pool);
00567 CXX_DELETE(_lftr,_etable_pool);
00568 if (WOPT_Enable_Hoisting)
00569 Delete_EXP_HOISTING(_exp_hoisting);
00570
00571 }
00572
00573 void
00574 COMP_UNIT::Do_load_pre(BOOL do_consts, BOOL do_loads)
00575 {
00576 MEM_POOL etable_pool, phi_pool, etable_local_pool;
00577
00578 OPT_POOL_Initialize(&etable_pool, "etable pool", FALSE, LPRE_DUMP_FLAG);
00579 OPT_POOL_Initialize(&phi_pool, "phi pool", FALSE, LPRE_DUMP_FLAG);
00580 OPT_POOL_Initialize(&etable_local_pool, "etable local pool", FALSE, LPRE_DUMP_FLAG);
00581 OPT_POOL_Push(&etable_pool, LPRE_DUMP_FLAG);
00582 OPT_POOL_Push(&phi_pool, LPRE_DUMP_FLAG);
00583 OPT_POOL_Push(&etable_local_pool, LPRE_DUMP_FLAG);
00584
00585 {
00586 ETABLE etable(Cfg(), Opt_stab(), Htable(), Arule(), 10,
00587 &etable_pool, &phi_pool, &etable_local_pool, this, PK_LPRE);
00588 etable.LPRE_set_do_consts(do_consts);
00589 etable.LPRE_set_do_loads(do_loads);
00590 etable.Perform_LPRE_optimization();
00591 }
00592
00593 OPT_POOL_Pop(&etable_local_pool, LPRE_DUMP_FLAG);
00594 OPT_POOL_Pop(&phi_pool, LPRE_DUMP_FLAG);
00595 OPT_POOL_Pop(&etable_pool, LPRE_DUMP_FLAG);
00596 OPT_POOL_Delete(&etable_local_pool, LPRE_DUMP_FLAG);
00597 OPT_POOL_Delete(&phi_pool, LPRE_DUMP_FLAG);
00598 OPT_POOL_Delete(&etable_pool, LPRE_DUMP_FLAG);
00599 }
00600
00601
00602
00603
00604 BOOL
00605 CODEREP::Is_rvi_const_candidate(const CODEREP *parent, INT whichkid, const OPT_STAB *opt_stab) const
00606 {
00607 if ( parent == NULL ) return FALSE;
00608
00609 #ifdef TARG_NVISA
00610
00611
00612
00613 if (Kind() == CK_RCONST) {
00614 if (MTYPE_is_float(Dtyp())) {
00615 return !Can_Be_Float_Immediate(Dtyp());
00616 }
00617 return false;
00618 }
00619 #endif
00620
00621 Is_True( (Kind() == CK_CONST) && MTYPE_is_integral(Dtyp()),
00622 ("CODEREP::Is_rvi_const_candidate: not an integer const") );
00623
00624 const MTYPE par_dtyp = parent->Dtyp();
00625 const INT64 con_val = Const_val();
00626 const CODEKIND par_ck = parent->Kind();
00627 const OPERATOR par_opr = (par_ck == CK_VAR) ? OPR_STID : parent->Opr();
00628
00629 #ifdef TARG_MIPS
00630 if (con_val == 0)
00631 return FALSE;
00632 #endif
00633
00634
00635
00636
00637 switch (par_opr) {
00638 case OPR_EQ: case OPR_NE:
00639 case OPR_LNOT:
00640 case OPR_CVT:
00641 if (parent->Dsctyp() == MTYPE_B)
00642 return FALSE;
00643 break;
00644 case OPR_SELECT:
00645 if (parent->Dsctyp() == MTYPE_B && whichkid == 0)
00646 return FALSE;
00647 break;
00648 default: ;
00649 }
00650
00651 ST * const stid_st = (par_ck == CK_VAR)
00652 ? opt_stab->St(parent->Aux_id()) : NULL;
00653
00654 return !Can_Be_Immediate(par_opr, con_val, par_dtyp, whichkid, stid_st);
00655 }
00656
00657
00658
00659
00660
00661
00662 BOOL
00663 CODEREP::Is_rvi_lda_candidate( const CODEREP *parent, INT whichkid, const OPT_STAB *opt_stab ) const
00664 {
00665 #if defined(TARG_X8664) || defined(TARG_IA32)
00666 return FALSE;
00667 #else
00668 if (parent == NULL) return FALSE;
00669
00670 Is_True( Kind() == CK_LDA,
00671 ("CODEREP::Is_rvi_lda_candidate: not a LDA") );
00672
00673 const OPERATOR par_opr
00674 = (parent->Kind() == CK_VAR) ? OPR_STID : parent->Opr();
00675 const WN_OFFSET lda_offset = Offset();
00676
00677 if (lda_offset == 0) return FALSE;
00678
00679 ST *lda_st = opt_stab->St(Lda_aux_id());
00680
00681 switch ( par_opr ) {
00682 case OPR_ILOAD:
00683 case OPR_ILOADX:
00684 case OPR_MLOAD:
00685 case OPR_ILDBITS:
00686
00687
00688 if ( this == parent->Ilod_base() || this == parent->Istr_base() ) {
00689 return !Uses_Small_Offset( lda_st, lda_offset );
00690 }
00691 return TRUE;
00692
00693 case OPR_CALL:
00694 case OPR_ICALL:
00695 case OPR_INTRINSIC_CALL:
00696 case OPR_PARM:
00697
00698
00699
00700 return !Uses_Small_Offset( lda_st, lda_offset );
00701
00702 case OPR_PICCALL:
00703
00704
00705 if ( whichkid == (parent->Kid_count() - 1) ) {
00706 if ( Enable_GOT_Call_Conversion ) {
00707
00708 return TRUE;
00709 }
00710 else {
00711
00712
00713 if ( (Gen_PIC_Call_Shared || Gen_PIC_Shared) &&
00714 !ST_visible_outside_dso(lda_st) )
00715 {
00716 return TRUE;
00717 }
00718 }
00719
00720 return FALSE;
00721 }
00722 else {
00723
00724
00725
00726
00727
00728 return !Uses_Small_Offset( lda_st, lda_offset );
00729 }
00730
00731 case OPR_STID:
00732
00733
00734
00735
00736
00737
00738 if ( ST_class(opt_stab->St(parent->Aux_id())) == CLASS_PREG &&
00739 Uses_Small_Offset( lda_st, lda_offset ) )
00740 {
00741
00742 return FALSE;
00743 }
00744 return TRUE;
00745
00746 default:
00747 return TRUE;
00748 }
00749 #endif
00750 }