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 #ifdef USE_PCH
00055 #include "opt_pch.h"
00056 #endif // USE_PCH
00057 #pragma hdrstop
00058
00059
00060 #ifdef _KEEP_RCS_ID
00061 #define opt_lftr2_CXX "opt_lftr2.cxx"
00062 static char *rcs_id = opt_lftr2_CXX"$Revision: 1.6 $";
00063 #endif
00064
00065 #include "opt_lftr2.h"
00066 #include "config_wopt.h"
00067 #include "opt_fold.h"
00068 #include "idx_32_set.h"
00069
00070
00071
00072
00073 LFTR::LFTR(ETABLE *etable, CODEMAP *htable, CFG *cfg, mUINT32 hash_size)
00074 {
00075 _lftr_on = WOPT_Enable_LFTR2 && etable->Pre_kind() == PK_EPRE;
00076 _exp_iter = NULL;
00077 if (Lftr_on()) {
00078 OPT_POOL_Initialize(&_mem_pool, "PRE LFTR mem pool", FALSE, LFTR_FLAG);
00079 OPT_POOL_Push(&_mem_pool, LFTR_FLAG);
00080
00081 _etable = etable;
00082 _htable = htable;
00083 _cfg = cfg;
00084 _trace = Get_Trace(TP_GLOBOPT, LFTR_FLAG);
00085 _num_substitutions = 0;
00086 _last_stmt = 0;
00087 _len = 0;
00088
00089
00090 Alloc_hash_vec(hash_size);
00091
00092
00093 _stmt_no.Set_Mem_Pool(&_mem_pool);
00094
00095 } else {
00096
00097 _etable = NULL;
00098 _htable = NULL;
00099 _cfg = NULL;
00100 _hash_vec = NULL;
00101 _trace = FALSE;
00102 }
00103 }
00104
00105
00106
00107
00108 LFTR::~LFTR(void)
00109 {
00110 if (Lftr_on()) {
00111 {
00112 BB_NODE *bb;
00113 CFG_ITER cfg_iter(Cfg());
00114 FOR_ALL_NODE(bb, cfg_iter, Init()) {
00115 STMTREP *stmt;
00116 STMTREP_ITER stmt_iter(bb->Stmtlist());
00117 FOR_ALL_NODE(stmt, stmt_iter, Init())
00118 stmt->Set_Bitpos(ILLEGAL_BP);
00119 }
00120 }
00121
00122
00123
00124 Free_hash_vec();
00125 _stmt_no.Free_array();
00126 OPT_POOL_Pop(&_mem_pool, LFTR_FLAG);
00127 OPT_POOL_Delete(&_mem_pool, LFTR_FLAG);
00128 Opt_tlog("LFTR2", 0, "comparisons substituted %d", Num_substitutions());
00129 }
00130 }
00131
00132
00133
00134
00135 void
00136 LFTR::Alloc_hash_vec(INT32 hash_size)
00137 {
00138 _hash_size = hash_size;
00139
00140
00141 _hash_vec = CXX_NEW_ARRAY(LFTR_VAR *, _hash_size+1, &_mem_pool);
00142 if (_hash_vec == NULL)
00143 ErrMsg (EC_No_Mem, "LFTR::Alloc_hash_vec, hash_vec");
00144 BZERO(_hash_vec, sizeof(LFTR_VAR *) * (_hash_size+1));
00145
00146 Is_Trace(Trace(),(TFile,"LFTR::Alloc_hash_vec(%d)\n",hash_size));
00147 }
00148
00149
00150
00151
00152 void
00153 LFTR::Free_hash_vec(void)
00154 {
00155 Is_True(_hash_vec != NULL,("LFTR::Free_hash_vec, it's already been freed"));
00156 CXX_DELETE_ARRAY(_hash_vec, &_mem_pool);
00157 _hash_vec = NULL;
00158 Is_Trace(Trace(),(TFile,"LFTR::Free_hash_vec\n"));
00159 }
00160
00161
00162
00163
00164
00165 LFTR_VAR *
00166 LFTR::Find_comp_list(AUX_ID lftr_var)
00167 {
00168 LFTR_VAR *ltmp = _hash_vec[Hash_lftr_var(lftr_var)];
00169 if (ltmp != NULL) {
00170 LFTR_VAR *tmp = ltmp->Find_comp_list(lftr_var);
00171 if (tmp != NULL) {
00172 Set_len(tmp->Size());
00173 return tmp;
00174 }
00175 }
00176 Set_len(0);
00177 return NULL;
00178 }
00179
00180
00181
00182
00183 LFTR_VAR *
00184 LFTR_VAR::Find_comp_list(AUX_ID lftr_var)
00185 {
00186 LFTR_VAR *ltmp;
00187 LFTR_VAR_ITER lftr_var_iter(this);
00188 FOR_ALL_NODE(ltmp, lftr_var_iter, Init()) {
00189 if (ltmp->Lftr_var() == lftr_var)
00190 return ltmp;
00191 }
00192 return NULL;
00193 }
00194
00195
00196
00197
00198 void
00199 LFTR::Clear_def_occurs(EXP_WORKLST *exp_worklst)
00200 {
00201 if (!Lftr_on())
00202 return;
00203
00204 EXP_OCCURS_PAIR *comp_list = Exp_hash(exp_worklst);
00205 if (comp_list != NULL) {
00206 EXP_OCCURS *exp_occ;
00207 EXP_ALL_REAL_ITER exp_iter(NULL, comp_list);
00208 FOR_ALL_NODE(exp_occ, exp_iter, Init())
00209 exp_occ->Set_def_occur(NULL);
00210 }
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 void
00226 LFTR::Lftr_comparison(CODEREP *cr, STMTREP *stmt, INT32 stmt_kid_num)
00227 {
00228 Is_True(Lftr_on(), ("LFTR::Lftr_comparison, LFTR not on"));
00229 Is_True(Is_comparison(cr), ("LFTR::Lftr_comparison, not a comparison"));
00230 if (cr->Kid_count() != 2)
00231 return;
00232 if (cr->Opnd(0)->Kind() == CK_OP && cr->Opnd(1)->Kind() == CK_OP)
00233 return;
00234
00235
00236 AUX_ID lftr_var = Find_lftr_var_id(cr);
00237 if (lftr_var == ILLEGAL_AUX_ID) {
00238 Is_Trace(Trace(),
00239 (TFile,"LFTR::Lftr_comparison, return 1, could not find lftr_var\n"));
00240 return;
00241 }
00242
00243 CODEREP *lhs, *rhs;
00244 BB_NODE *bb = stmt->Bb();
00245 lhs = Set_lhs_and_rhs(cr,&rhs);
00246 const BB_LOOP *loop = Cfg()->Find_innermost_loop_contains( bb );
00247 if (loop &&
00248 loop->True_body_set()->MemberP(bb)) {
00249 if (rhs && !loop->Invariant_cr(rhs)) {
00250 Is_Trace(Trace(),
00251 (TFile,"LFTR::Lftr_comparison, return 3 - RHS is not invariant\n"));
00252 return;
00253 }
00254 if (loop->Invariant_cr(lhs)) {
00255 Is_Trace(Trace(),
00256 (TFile,"LFTR::Lftr_comparison, return 4 - LHS is invariant\n"));
00257 return;
00258 }
00259 if (loop->Lftr_non_candidates() &&
00260 loop->Lftr_non_candidates()->MemberP(lftr_var)) {
00261 Is_Trace(Trace(),
00262 (TFile,"LFTR::Lftr_comparison, return 6 - LHS is in Lftr_non_candidates\n"));
00263 return;
00264 }
00265 Is_Trace(Trace(),
00266 (TFile,"LFTR::Lftr_comparison, found comparison inside a loop\n"));
00267 } else {
00268 #if 0 // we may want to re-visit non-loop LFTR some day
00269 if (rhs && rhs->Kind() != CK_CONST) {
00270 Is_Trace(Trace(),
00271 (TFile,"LFTR::Lftr_comparison, return 5 - RHS is not a constant\n"));
00272 }
00273 #endif
00274 Is_Trace(Trace(),
00275 (TFile,"LFTR::Lftr_comparison, found comparison outside a loop\n"));
00276 return;
00277 }
00278
00279
00280 Is_Trace(Trace(),(TFile," lftr_var = "));
00281 Is_Trace_cmd(Trace(),lhs->Print(0,TFile));
00282 Is_Trace(Trace(),(TFile," rhs = "));
00283 Is_Trace_cmd(Trace(),rhs->Print(0,TFile));
00284
00285
00286 Add_comparison(cr, lftr_var, stmt, stmt_kid_num);
00287 }
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 void
00299 LFTR::Add_comparison(CODEREP *cr, AUX_ID lftr_var, STMTREP *stmt,
00300 INT32 stmt_kid_num)
00301 {
00302 Is_True(lftr_var != ILLEGAL_AUX_ID,
00303 ("LFTR::Add_comparison, lftr_var not valid"));
00304 Is_True(cr != NULL,("LFTR::Add_comparison, NULL CR"));
00305 IDX_32 hash_index = Hash_lftr_var(lftr_var);
00306
00307
00308 LFTR_VAR *comp_list;
00309 if (_hash_vec[hash_index] == NULL) {
00310 Is_Trace(Trace(),
00311 (TFile,"LFTR::Add_comparison, adding to NULL list %d\n",
00312 hash_index));
00313 Is_Trace_cmd(Trace(),stmt->Print(TFile));
00314
00315 _hash_vec[hash_index] = comp_list = CXX_NEW(LFTR_VAR(lftr_var),&_mem_pool);
00316 } else {
00317 LFTR_VAR_ITER lftr_var_iter(_hash_vec[hash_index]);
00318 FOR_ALL_NODE(comp_list, lftr_var_iter, Init()) {
00319 if (comp_list->Lftr_var() == lftr_var)
00320 break;
00321 }
00322 if (comp_list == NULL) {
00323 comp_list = CXX_NEW(LFTR_VAR(lftr_var),&_mem_pool);
00324 Is_Trace(Trace(),
00325 (TFile,"LFTR::Add_comparison, creating comparison list %d\n",
00326 hash_index));
00327 Is_Trace_cmd(Trace(),stmt->Print(TFile));
00328 _hash_vec[hash_index]->Insert_Before(comp_list);
00329 _hash_vec[hash_index] = comp_list;
00330 } else {
00331 Is_Trace(Trace(),
00332 (TFile,"LFTR::Add_comparison, adding to comparison list %d\n",
00333 hash_index));
00334 Is_Trace_cmd(Trace(),stmt->Print(TFile));
00335 }
00336 }
00337 Is_True(comp_list != NULL, ("LFTR::Add_comparison, NULL LFTR_VAR"));
00338
00339 comp_list->Add_comparison(cr, stmt, stmt_kid_num, &_mem_pool, Trace());
00340 }
00341
00342
00343
00344
00345
00346 void
00347 LFTR_VAR::Add_comparison(CODEREP *cr,
00348 STMTREP *stmt,
00349 INT32 stmt_kid_num,
00350 MEM_POOL *mem_pool,
00351 BOOL trace)
00352 {
00353 BB_NODE *bb = stmt->Bb();
00354 EXP_OCCURS *stmt_first_comp = NULL;
00355
00356 Is_Trace(trace, (TFile, "LFTR_VAR::Add_comparison: checking for\n"));
00357 Is_Trace_cmd(trace, cr->Print(3, TFile));
00358 Is_Trace(trace, (TFile, " in kid %d of\n", stmt_kid_num));
00359 Is_Trace_cmd(trace, stmt->Print(TFile));
00360
00361 EXP_OCCURS *tmp_occ, *prev = NULL;
00362 EXP_OCCURS_ITER tmp_occ_iter;
00363 FOR_ALL_NODE(tmp_occ, tmp_occ_iter, Init(_comp_list)) {
00364 Is_Trace(trace, (TFile, " --- examining (stmt kid %d)\n",
00365 tmp_occ->Stmt_kid_num()));
00366 Is_Trace_cmd(trace, tmp_occ->Print(TFile));
00367 if (bb->Dom_dfs_id() < tmp_occ->Bb()->Dom_dfs_id()) {
00368 Is_Trace(trace, (TFile, " --- breaking (BB)\n"));
00369 break;
00370 }
00371 if (bb == tmp_occ->Bb() &&
00372 stmt->Stmt_order_less_or_equal(tmp_occ->Stmt())) {
00373 if (stmt == tmp_occ->Stmt()) {
00374 stmt_first_comp = tmp_occ;
00375 }
00376 Is_Trace(trace, (TFile, " --- breaking (stmt) (%sNULL)\n",
00377 (stmt_first_comp != NULL ? "non-" : "")));
00378 break;
00379 }
00380 prev = tmp_occ;
00381 }
00382
00383 BOOL duplicate = FALSE;
00384 if (stmt_first_comp != NULL) {
00385 Is_Trace(trace, (TFile, "Checking for duplicates...\n"));
00386
00387
00388
00389 FOR_ALL_NODE(tmp_occ, tmp_occ_iter, Init(stmt_first_comp)) {
00390 if (duplicate || (tmp_occ->Stmt() != stmt)) {
00391 break;
00392 }
00393 if (tmp_occ->Stmt_kid_num() == stmt_kid_num &&
00394 tmp_occ->Occurrence() == cr) {
00395 duplicate = TRUE;
00396 }
00397 if (duplicate || tmp_occ->Stmt() != stmt) {
00398 break;
00399 }
00400 }
00401 }
00402 if (!duplicate) {
00403
00404
00405 Is_Trace(trace, (TFile, "No duplicate found\n"));
00406
00407
00408
00409 EXP_OCCURS *new_occur = CXX_NEW(EXP_OCCURS(cr, stmt, NULL, TRUE),
00410 mem_pool);
00411 new_occur->Set_kind(EXP_OCCURS::OCC_COMP_OCCUR);
00412 new_occur->Set_stmt_kid_num(stmt_kid_num);
00413 if (prev != NULL) {
00414 new_occur->Set_Next(prev->Next());
00415 prev->Set_Next(new_occur);
00416 }
00417 else {
00418 new_occur->Set_Next(_comp_list);
00419 _comp_list = new_occur;
00420 }
00421 Inc_list_size();
00422 }
00423 else {
00424 Is_Trace(trace, (TFile, " --- duplicate; no insertion\n"));
00425 }
00426 }
00427
00428
00429
00430
00431
00432
00433
00434 void
00435 LFTR_VAR::Add_comparison(EXP_OCCURS *new_occur)
00436 {
00437 Is_True(new_occur->Occ_kind() == EXP_OCCURS::OCC_COMP_OCCUR,
00438 ("LFTR_VAR::Add_comparison, wrong occur kind"));
00439
00440 if (_comp_list == NULL)
00441 _comp_list = new_occur;
00442 else {
00443 EXP_OCCURS *tmp_occ, *prev = NULL;
00444 EXP_OCCURS_ITER tmp_occ_iter;
00445 FOR_ALL_NODE(tmp_occ, tmp_occ_iter, Init(_comp_list)) {
00446 if (new_occur->Bb()->Dom_dfs_id() < tmp_occ->Bb()->Dom_dfs_id())
00447 break;
00448 if (new_occur->Bb() == tmp_occ->Bb() &&
00449 new_occur->Stmt_order_less_or_equal(tmp_occ))
00450 break;
00451 prev = tmp_occ;
00452 }
00453 if (prev != NULL) {
00454 new_occur->Set_Next(prev->Next());
00455 prev->Set_Next(new_occur);
00456 } else {
00457 new_occur->Set_Next(_comp_list);
00458 _comp_list = new_occur;
00459 }
00460 }
00461 Inc_list_size();
00462 }
00463
00464
00465
00466
00467 void
00468 LFTR::Remove_comparison(EXP_OCCURS *comp, AUX_ID lftr_var)
00469 {
00470 Is_True(comp != NULL, ("LFTR::Remove_comparison, NULL occur"));
00471 Is_True(lftr_var != ILLEGAL_AUX_ID,
00472 ("LFTR::Remove_comparison, bad lftr_var"));
00473
00474 LFTR_VAR *list = Find_comp_list(lftr_var);
00475 Is_True(list != NULL, ("LFTR::Remove_comparison, NULL lftr_var list"));
00476 EXP_OCCURS *exp_occ, *prev = NULL;
00477 EXP_OCCURS_ITER exp_iter;
00478 FOR_ALL_NODE(exp_occ, exp_iter, Init(list->Occ_list())) {
00479 if (exp_occ == comp) {
00480 if (prev == NULL)
00481 list->Set_occ_list(exp_occ->Next());
00482 else
00483 prev->Set_Next(exp_occ->Next());
00484 list->Dec_list_size();
00485 return;
00486 }
00487 prev = exp_occ;
00488 }
00489 Is_True(FALSE, ("LFTR::Remove_comparison, cound not find occur"));
00490 }
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500 void
00501 LFTR::Remove_lftr_non_candidates(void)
00502 {
00503 LFTR_VAR *comp_list;
00504 EXP_OCCURS *occur, *prev;
00505 EXP_OCCURS_ITER occur_iter;
00506 INT32 i;
00507 for (i=0; i != _hash_size; i++) {
00508 if (_hash_vec[i] == NULL)
00509 continue;
00510 LFTR_VAR_ITER lftr_var_iter(_hash_vec[i]);
00511 FOR_ALL_NODE(comp_list, lftr_var_iter, Init()) {
00512 prev = NULL;
00513 FOR_ALL_NODE(occur, occur_iter, Init(comp_list->Occ_list())) {
00514 BB_NODE *bb = occur->Bb();
00515 BB_LOOP *loop = bb->Innermost();
00516 if (loop == NULL || loop->Lftr_non_candidates() == NULL) {
00517 prev = occur;
00518 continue;
00519 }
00520 if (loop->Lftr_non_candidates()->MemberP(comp_list->Lftr_var())) {
00521
00522 if (prev == NULL)
00523 comp_list->Set_occ_list(occur->Next());
00524 else prev->Set_Next(occur->Next());
00525 comp_list->Dec_list_size();
00526 Is_Trace(Trace(),(TFile,"LFTR::Remove_lftr_non_candidate removes in BB%d:\n", bb->Id()));
00527 Is_Trace_cmd(Trace(),occur->Print(TFile));
00528 }
00529 else prev = occur;
00530 }
00531 }
00532 }
00533 }
00534
00535
00536
00537
00538 void
00539 LFTR::Assign_stmt_no(STMTREP *stmt)
00540 {
00541 Is_True(Lftr_on(),("LFTR::Assign_stmt_no, LFTR not on"));
00542 _stmt_no.AddElement(_last_stmt);
00543 stmt->Set_stmt_id(_stmt_no.Lastidx());
00544 _last_stmt++;
00545 }
00546
00547
00548
00549
00550
00551
00552 EXP_OCCURS_PAIR *
00553 LFTR::Exp_hash(EXP_WORKLST *worklst)
00554 {
00555 EXP_OCCURS_PAIR *comp_occurs = &worklst->Comp_occurs();
00556 comp_occurs->Clear();
00557
00558 CODEREP *exp = worklst->Exp();
00559 AUX_ID prev_aux_id = ILLEGAL_AUX_ID;
00560 if (Is_lftr_exp(exp)) {
00561
00562 for (INT i = 0; i < exp->Kid_count(); i++) {
00563 CODEREP *kid = exp->Opnd(i);
00564 if (kid->Kind() == CK_VAR && kid->Aux_id() != prev_aux_id) {
00565 AUX_ID lftr_var_id = kid->Aux_id();
00566 prev_aux_id = lftr_var_id;
00567 if (lftr_var_id != ILLEGAL_AUX_ID) {
00568 LFTR_VAR *lftr_var = Find_comp_list(lftr_var_id);
00569 if (lftr_var != NULL)
00570 comp_occurs->Set_occ(i, lftr_var->Occ_list());
00571 }
00572 }
00573 }
00574 }
00575 return comp_occurs;
00576 }
00577
00578
00579
00580
00581
00582
00583 CODEREP *
00584 LFTR::Find_lftr_var(CODEREP *cr)
00585 {
00586
00587
00588 CODEREP *lhs, *rhs;
00589 lhs = Set_lhs_and_rhs(cr,&rhs);
00590 if (lhs->Kind() == CK_VAR) {
00591
00592
00593
00594 if (rhs == NULL || inCODEKIND(rhs->Kind(),CK_CONST|CK_VAR|CK_OP|CK_LDA))
00595 return lhs;
00596 }
00597 return NULL;
00598 }
00599
00600
00601
00602
00603
00604 CODEREP *
00605 LFTR::Find_lftr_var(CODEREP *exp, CODEREP *var)
00606 {
00607 if (exp->Kind() != CK_OP) return NULL;
00608
00609 for (INT i = 0; i < exp->Kid_count(); i++) {
00610 CODEREP *kid = exp->Opnd(i);
00611 if (kid->Kind() == CK_VAR && kid->Aux_id() == var->Aux_id())
00612 return kid;
00613 }
00614 return NULL;
00615 }
00616
00617
00618
00619
00620
00621
00622 static CODEREP *
00623 Find_aux_id_use_in_expr(AUX_ID id, CODEREP *cr)
00624 {
00625 CODEREP *retval;
00626 INT i;
00627
00628 switch (cr->Kind()) {
00629 case CK_VAR:
00630 if (cr->Aux_id() == id)
00631 return cr;
00632 else
00633 return NULL;
00634 case CK_IVAR:
00635 Is_True(cr->Ilod_base(),
00636 ("Find_aux_id_use_in_expr: Ilod_base is NULL"));
00637 return Find_aux_id_use_in_expr(id, cr->Ilod_base());
00638
00639 case CK_OP:
00640 for (i = 0; i < cr->Kid_count(); i++) {
00641 retval = Find_aux_id_use_in_expr(id, cr->Opnd(i));
00642 if (retval != NULL)
00643 return retval;
00644 }
00645
00646 default:
00647 return NULL;
00648 }
00649 }
00650
00651
00652
00653
00654
00655
00656 void
00657 LFTR::Check_for_obsolete_comparison(EXP_OCCURS *comp)
00658 {
00659 if (comp->Obsolete_comparison())
00660 return;
00661 STMTREP *stmt = comp->Stmt();
00662 INT32 kid_num = comp->Stmt_kid_num();
00663 BOOL obsolete;
00664
00665 if (OPERATOR_is_call(stmt->Opr()))
00666 obsolete = ! stmt->Rhs()->Opnd(kid_num)->Contains(comp->Occurrence());
00667 else if (OPERATOR_is_store(stmt->Opr())) {
00668 switch (kid_num) {
00669 case 0:
00670 obsolete = ! stmt->Rhs()->Contains(comp->Occurrence());
00671 break;
00672 case 1:
00673 if (stmt->Lhs()->Kind() == CK_IVAR) {
00674
00675
00676 obsolete = ! stmt->Lhs()->Istr_base()->Contains(comp->Occurrence());
00677 }
00678 else {
00679 obsolete = ! stmt->Lhs()->Contains(comp->Occurrence());
00680 }
00681 break;
00682 case 2:
00683 obsolete = ! stmt->Lhs()->Mstore_size()->Contains(comp->Occurrence());
00684 break;
00685 default:
00686 Is_True(FALSE, ("LFTR::Check_for_obsolete_comparison: bad stmt_kid_num"));
00687 }
00688 }
00689 else if (stmt->Opr() == OPR_PREFETCH)
00690 obsolete = ! stmt->Rhs()->Ilod_base()->Contains(comp->Occurrence());
00691 else obsolete = ! stmt->Rhs()->Contains(comp->Occurrence());
00692
00693 if (obsolete) {
00694 comp->Set_obsolete_comparison();
00695 Is_Trace(Trace(), (TFile, "LFTR::Check_for_obsolete_comparison finds:\n"));
00696 Is_Trace_cmd(Trace(), comp->Print(TFile));
00697 Is_Trace(Trace(), (TFile, " no "
00698 "longer in\n"));
00699 Is_Trace_cmd(Trace(), stmt->Print(TFile));
00700 }
00701 }
00702
00703
00704
00705
00706
00707
00708
00709 BOOL
00710 LFTR::Can_only_increase(CODEREP *x, AUX_ID aux_id)
00711 {
00712 switch (x->Kind()) {
00713 case CK_LDA:
00714 return TRUE;
00715 case CK_CONST:
00716 return (x->Const_val() >> 15) == 0;
00717 case CK_RCONST:
00718 return FALSE;
00719 case CK_VAR:
00720 return x->Aux_id() == aux_id;
00721 case CK_IVAR:
00722 return FALSE;
00723 case CK_OP:
00724 switch (x->Opr()) {
00725 case OPR_NEG: case OPR_SUB:
00726 return FALSE;
00727 case OPR_ADD: case OPR_MPY:
00728 {
00729 for (INT i = 0; i < x->Kid_count(); i++) {
00730 if (! Can_only_increase(x->Opnd(i), aux_id))
00731 return FALSE;
00732 }
00733 }
00734 return TRUE;
00735 default: ;
00736 }
00737 default: ;
00738 }
00739 return FALSE;
00740 }
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851 void
00852 LFTR::Replace_comparison(EXP_OCCURS *comp, BOOL cur_expr_is_sr_candidate)
00853 {
00854 Is_Trace(Trace(),(TFile,"LFTR::Replace_comparison called on:\n"));
00855 Is_Trace_cmd(Trace(),comp->Print(TFile));
00856 Is_Trace_cmd(Trace(),comp->Occurrence()->Print(0,TFile));
00857 Is_True(comp->Occ_kind() == EXP_OCCURS::OCC_COMP_OCCUR,
00858 ("LFTR::Replace_comparison, comp is not a comp occur"));
00859
00860 if (WOPT_Enable_LFTR2_Limit != -1 && WOPT_Enable_LFTR2_Limit <= Num_substitutions()) {
00861 Is_Trace(Trace(), (TFile,"LFTR return : exceeded limit\n"));
00862 return;
00863 }
00864
00865
00866
00867 Check_for_obsolete_comparison(comp);
00868 if (comp->Obsolete_comparison())
00869 return;
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890 if (cur_expr_is_sr_candidate &&
00891 !comp->Bb()->Innermost()->Is_flag_set(LOOP_HAS_REAL_OCC)) {
00892 Is_Trace(Trace(), (TFile, "LFTR return 0 - no real occ in same "
00893 "loop nest level\n"));
00894 return;
00895 }
00896 else {
00897 Is_Trace(Trace(), (TFile, "Loop headed at BB%d contains real occ\n",
00898 comp->Bb()->Innermost()->Header()->Id()));
00899 }
00900
00901 EXP_OCCURS *tos = comp->Def_occur();
00902 if (tos == NULL) {
00903 Is_Trace(Trace(), (TFile,"LFTR return 1 - no dominating tos\n"));
00904 return;
00905 }
00906
00907 Is_True(tos->Bb()->Dominates(comp->Bb()) &&
00908 (tos->Bb() != comp->Bb() ||
00909 tos->Occ_kind() == EXP_OCCURS::OCC_PHI_OCCUR ||
00910 tos->Enclosed_in_stmt()->Stmt_id() <=
00911 comp->Enclosed_in_stmt()->Stmt_id()),
00912 ("LFTR::Replace_comparison, tos does not dominate comp"));
00913
00914 Is_True(tos->Occ_kind() == EXP_OCCURS::OCC_PHI_OCCUR ||
00915 tos->Occ_kind() == EXP_OCCURS::OCC_REAL_OCCUR,
00916 ("LFTR::Replace_comparison, unexpected tos kind"));
00917
00918 if (comp->E_version() == EXP_OCCURS::ILLEGAL_E_VERSION) {
00919 Is_Trace(Trace(),(TFile,"LFTR return 2 - no e-version for comp occur\n"));
00920 return;
00921 }
00922
00923
00924
00925 Is_True(comp->E_version() == tos->E_version(),
00926 ("LFTR::Replace_comparison, e-version of tos and comp differ"));
00927
00928
00929 Is_True(tos->Occurrence()->Kind() == CK_OP &&
00930 tos->Occurrence()->Opnd(0)->Kind() != CK_OP &&
00931 (tos->Occurrence()->Kid_count() == 1 ||
00932 tos->Occurrence()->Opnd(1)->Kind() != CK_OP),
00933 ("LFTR::Replace_comparison, tos->Occurrence is compound"));
00934
00935
00936 if (MTYPE_is_float(comp->Occurrence()->Dsctyp()))
00937 return;
00938
00939
00940 CODEREP *comp_lftr_var = Find_lftr_var(comp->Occurrence());
00941
00942
00943 CODEREP *tos_lftr_var = Find_lftr_var(tos->Occurrence(), comp_lftr_var);
00944
00945 if (comp_lftr_var == NULL || tos_lftr_var == NULL) {
00946 Is_Trace(Trace(), (TFile, "LFTR return 3 - could not find a lftr_var, "
00947 "comp=0x%p, tos=0x%p\n", comp_lftr_var,
00948 tos_lftr_var));
00949 return;
00950 }
00951 else {
00952 Is_Trace(Trace(), (TFile, "comp_lftr_var: "));
00953 Is_Trace_cmd(Trace(), comp_lftr_var->Print(0, TFile));
00954 Is_Trace(Trace(), (TFile, " tos_lftr_var: "));
00955 Is_Trace_cmd(Trace(), tos_lftr_var->Print(0, TFile));
00956 }
00957
00958 AUX_ID comp_lftr_var_id = comp_lftr_var->Aux_id();
00959 AUX_ID tos_lftr_var_id = tos_lftr_var->Aux_id();
00960
00961
00962 if (comp_lftr_var_id==ILLEGAL_AUX_ID || tos_lftr_var_id==ILLEGAL_AUX_ID) {
00963 Is_Trace(Trace(),
00964 (TFile,"LFTR return 4 - illegal aux_id comp_id=%d, tos_id=%d\n",
00965 comp_lftr_var_id,tos_lftr_var_id));
00966 return;
00967 }
00968
00969
00970 CODEREP *tempcr = tos->Temp_cr();
00971
00972 if (tos->Occ_kind() == EXP_OCCURS::OCC_PHI_OCCUR) {
00973 STMTREP *iv_defstmt = comp_lftr_var->Defstmt();
00974 if (iv_defstmt == NULL) {
00975
00976
00977 } else if (iv_defstmt->Bb() != tos->Bb() &&
00978 iv_defstmt->Bb()->Dominates(tos->Bb())) {
00979
00980
00981 } else {
00982 CODEREP *cr = Find_SR_tempcr(iv_defstmt,tempcr);
00983 if (cr == NULL) {
00984 Is_Trace(Trace(),(TFile,"LFTR return 6 - temp not found\n"));
00985 return;
00986 }
00987
00988 #ifdef KEY
00989 if (iv_defstmt->Iv_update() && iv_defstmt->Repaired() && tempcr->Aux_id() == cr->Aux_id()) {
00990 #else
00991 if (iv_defstmt->Iv_update() && tempcr->Aux_id() == cr->Aux_id()) {
00992 #endif
00993
00994 Is_True(tempcr != cr, ("LFTR::Replace_comparison, tempcr is same"));
00995 tempcr = cr;
00996 }
00997 }
00998 } else {
00999
01000 Is_True((!tos->Save_to_temp() && tempcr == NULL) || tempcr,
01001 ("LFTR::Replace_comparison, tempcr is not really a tempcr"));
01002 if (tempcr == NULL) {
01003 Is_Trace(Trace(),(TFile,"LFTR return 7 - no tempcr for real tos\n"));
01004 return;
01005 }
01006 }
01007
01008
01009
01010
01011
01012 if (tempcr->Is_flag_set(CF_DEF_BY_PHI)) {
01013
01014
01015
01016
01017
01018 Is_Trace(Trace(),
01019 (TFile, "LFTR::Replace_comparison: temp is def by phi\n"));
01020 if (tos_lftr_var != comp_lftr_var) {
01021 Is_Trace(Trace(), (TFile, "LFTR return 8 - lftr var in comp "
01022 "not current at temp def\n"));
01023 return;
01024 }
01025 }
01026 else {
01027
01028
01029 FmtAssert(!tempcr->Is_flag_set(CF_DEF_BY_CHI),
01030 ("LFTR::Replace_comparison: tempcr must not be def by chi"));
01031
01032
01033
01034
01035
01036
01037
01038
01039 CODEREP *temp_lftr_var = Find_aux_id_use_in_expr(tos_lftr_var_id,
01040 tempcr->Defstmt()->Rhs());
01041
01042 if (temp_lftr_var == NULL) {
01043
01044
01045 STMTREP *lftr_var_def;
01046 for (lftr_var_def = tempcr->Defstmt();
01047 lftr_var_def;
01048 lftr_var_def = lftr_var_def->Prev()) {
01049 if (OPERATOR_is_scalar_store (lftr_var_def->Opr())) {
01050 if (lftr_var_def->Lhs()->Aux_id() == tos_lftr_var_id) {
01051
01052 temp_lftr_var = lftr_var_def->Lhs();
01053 break;
01054 }
01055 }
01056 else {
01057 Is_True(OPERATOR_is_scalar_istore (lftr_var_def->Opr()) &&
01058 lftr_var_def->Is_RHS_saved(),
01059 ("LFTR::Replace_comparison: "
01060 "String of injury repairs must not be polluted"));
01061 }
01062 }
01063 FmtAssert(lftr_var_def != NULL,
01064 ("LFTR:Replace_comparison: cannot find lftr var version"));
01065 Is_Trace(Trace(), (TFile, "LFTR::Replace_comparison: "
01066 "lftr var in lhs of repaired injury\n"));
01067 }
01068 else {
01069 Is_Trace(Trace(), (TFile, "LFTR::Replace_comparison: "
01070 "lftr var in rhs of save to temp\n"));
01071 }
01072
01073
01074
01075 if (temp_lftr_var != comp_lftr_var) {
01076 Is_Trace(Trace(), (TFile, "LFTR return 9 - lftr var in comp "
01077 "not current at temp def\n"));
01078 return;
01079 }
01080 }
01081
01082
01083 if (MTYPE_size_min(tempcr->Dtyp()) < MTYPE_size_min(comp_lftr_var->Dtyp()))
01084 return;
01085
01086 NUMBER factor;
01087 if (Find_one_variant(comp->Bb(), comp_lftr_var, tos->Occurrence(), &factor,
01088 Htable()) != ONE_VARIANT) {
01089 return;
01090 }
01091 else {
01092 Is_Trace(Trace(), (TFile, "LFTR var variant at BB%d "
01093 "(loop head at BB%d)\n", comp->Bb()->Id(),
01094 comp->Bb()->Innermost()->Header()->Id()));
01095 }
01096
01097 BOOL eq_neq = comp->Occurrence()->Opr() == OPR_EQ ||
01098 comp->Occurrence()->Opr() == OPR_NE;
01099
01100 if (factor.Value() < 0 &&
01101 MTYPE_is_unsigned(comp->Occurrence()->Dsctyp()) && ! eq_neq)
01102 return;
01103
01104 #if 0
01105
01106
01107
01108 {
01109 CODEREP *comp_cr = comp->Occurrence();
01110 if (MTYPE_is_unsigned(comp_cr->Dsctyp()) &&
01111 comp_cr->Opr() != OPR_EQ &&
01112 comp_cr->Opr() != OPR_NE &&
01113 comp_cr->Opnd(1)->Kind() == CK_CONST &&
01114 comp_cr->Opnd(1)->Const_val() == 0)
01115 if (tos->Occurrence()->Opr() != OPR_MPY)
01116 return;
01117 }
01118 #endif
01119
01120
01121
01122 if (factor.Desc() == NUMBER_UNKNOWN)
01123 return;
01124
01125 ADDRESSABILITY addressable = tos->Occurrence()->Check_if_result_is_address(Htable()->Sym());
01126
01127 if (MTYPE_is_unsigned(comp->Occurrence()->Dsctyp()) && ! eq_neq &&
01128 addressable != ADDRESSABILITY_IS_ADDRESS &&
01129 ! Can_only_increase(tos->Occurrence(), tos_lftr_var_id))
01130 return;
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147 const BB_LOOP *loop = Cfg()->Find_innermost_loop_contains(comp->Bb());
01148 Is_True(loop != NULL,
01149 ("LFTR::Replace_comparison: comparison must be in a loop"));
01150
01151 BB_NODE *head = loop->Header();
01152 Is_True(head != NULL,
01153 ("LFTR::Replace_comparison: loop head must not be NULL"));
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163 if (Etable()->Lookup_var_phi(head, tempcr->Aux_id()) == NULL) {
01164 Is_Trace(Trace(), (TFile, "LFTR::Replace_comparison: return 10 - "
01165 "lftr var not recognized as loop induction var"));
01166 return;
01167 }
01168 else {
01169 Is_Trace(Trace(), (TFile, "LFTR:Replace_comparison: Loop head "
01170 "is BB%d\n", head->Id()));
01171 }
01172
01173
01174 {
01175 CODEREP *rhs_template =
01176 Alloc_stack_cr(tos->Occurrence()->Extra_ptrs_used());
01177 rhs_template->Copy(*tos->Occurrence());
01178 CODEREP *new_cr, *fold_cr;
01179 FOLD ftmp;
01180 new_cr = Replace_lftr_var(rhs_template,comp_lftr_var_id,
01181 comp->Occurrence()->Opnd(1));
01182 OPERATOR opr = new_cr->Opr();
01183
01184 #ifdef TARG_X8664
01185 if (opr != OPR_CVT)
01186 #endif
01187 {
01188
01189 CODEREP *kid0 = new_cr->Opnd(0);
01190 CODEREP *kid1 = new_cr->Opnd(1);
01191 if (kid0 == NULL || kid1 == NULL) return;
01192 NUMBER n1,n2,n3;
01193 if (kid0->Kind() == CK_CONST && kid1->Kind() == CK_CONST) {
01194 n1.Set_const(kid0->Const_val());
01195 n2.Set_const(kid1->Const_val());
01196 n3.Eval2(opr, &n1, &n2);
01197 if (n3.Desc() != NUMBER_KNOWN ||
01198 !n3.Representable_in_nbits(MTYPE_size_min(new_cr->Dtyp())))
01199 return;
01200 } else if (kid0->Kind() == CK_LDA && kid1->Kind() == CK_CONST) {
01201 n1.Set_const(kid0->Offset());
01202 n2.Set_const(kid1->Const_val());
01203 n3.Eval2(opr, &n1, &n2);
01204 if (n3.Desc() != NUMBER_KNOWN ||
01205 !n3.Representable_in_nbits(new_cr->Offset_nbits()))
01206 return;
01207 } else if (kid0->Kind() == CK_CONST && kid1->Kind() == CK_LDA && opr == OPR_ADD) {
01208 n1.Set_const(kid0->Const_val());
01209 n2.Set_const(kid1->Offset());
01210 n3.Eval2(opr, &n1, &n2);
01211 if (n3.Desc() != NUMBER_KNOWN ||
01212 !n3.Representable_in_nbits(new_cr->Offset_nbits()))
01213 return;
01214 }
01215 }
01216
01217 if (comp->Occurrence()->Opnd(1)->Kind() != CK_OP)
01218 fold_cr = ftmp.Fold_Expr(new_cr);
01219 else fold_cr = NULL;
01220
01221 if (fold_cr == NULL) {
01222 new_cr->Set_coderep_id(0);
01223 fold_cr = Htable()->Rehash(new_cr);
01224 }
01225
01226
01227
01228
01229 CODEREP *comparison_cr = CXX_NEW(CODEREP, &_mem_pool);
01230 comparison_cr->Init_op(comp->Occurrence()->Op(), 2);
01231
01232 Is_Trace(Trace(),(TFile,"LFTR::Replace_comparison, %dth committed\n",
01233 _num_substitutions+1));
01234 Is_Trace_cmd(Trace(),Print_occ(TFile,"tos:",tos));
01235 Is_Trace(Trace(),(TFile,"tempcr:\n"));
01236 Is_Trace_cmd(Trace(),tempcr->Print(0,TFile));
01237
01238
01239 OPERATOR new_compare_opr = comparison_cr->Opr();
01240 #ifdef KEY
01241 MTYPE new_compare_type = tempcr->Dtyp();
01242
01243 new_compare_type = Mtype_TransferSign(comparison_cr->Dsctyp(),
01244 new_compare_type);
01245 #else
01246 MTYPE new_compare_type = comparison_cr->Dsctyp();
01247 if (addressable == ADDRESSABILITY_IS_ADDRESS &&
01248 MTYPE_is_signed(new_compare_type)) {
01249
01250 new_compare_type = Mtype_from_mtype_class_and_size(MTYPE_CLASS_UNSIGNED,
01251 MTYPE_size_min(new_compare_type)/8);
01252 }
01253 #endif
01254 if (factor.Value() < 0 && ! eq_neq) {
01255 switch (new_compare_opr) {
01256 case OPR_LT:
01257 new_compare_opr = OPR_GT;
01258 break;
01259 case OPR_LE:
01260 new_compare_opr = OPR_GE;
01261 break;
01262 case OPR_GT:
01263 new_compare_opr = OPR_LT;
01264 break;
01265 case OPR_GE:
01266 new_compare_opr = OPR_LE;
01267 break;
01268 }
01269 }
01270 comparison_cr->Set_opr(new_compare_opr);
01271 comparison_cr->Set_dsctyp(new_compare_type);
01272
01273 comparison_cr->Set_opnd(1, fold_cr);
01274
01275
01276 Is_True(comp->Occurrence()->Opnd(0)->Kind() == CK_VAR,
01277 ("LFTR::Replace_comparison, lhs must be var"));
01278 comparison_cr->Set_opnd(0, tempcr);
01279
01280 if (comp->Stmt()->Op() == OPC_TRUEBR||comp->Stmt()->Op() == OPC_FALSEBR){
01281 BB_LOOP *loop = comp->Bb()->Loop();
01282 if ( loop != NULL && loop->Loopback() == comp->Bb() )
01283 loop->Set_iv_replacement(tempcr);
01284 }
01285
01286 Is_Trace(Trace(),(TFile,"LFTR::Replace_comparison, new cr:\n"));
01287 Is_Trace_cmd(Trace(),comparison_cr->Print(0,TFile));
01288
01289
01290 Is_True(Find_lftr_var_id(comparison_cr) != ILLEGAL_AUX_ID,
01291 ("LFTR::Replace_comparison, can't find new lftr_var"));
01292
01293
01294
01295
01296 Remove_comparison(comp, comp_lftr_var_id);
01297 if (comp->Occurrence()->Opnd(1)->Kind() != CK_OP) {
01298
01299
01300 Etable()->Remove_real_occurrence(comp->Occurrence(),
01301 comp->Enclosed_in_stmt());
01302 }
01303
01304
01305 comparison_cr = Htable()->Rehash(comparison_cr, FALSE);
01306
01307 Etable()->Replace_by_temp(comp, comparison_cr);
01308
01309 if (comparison_cr->Opnd(1)->Kind() == CK_OP) {
01310 if (comp->Occurrence()->Opnd(1)->Kind() != CK_OP) {
01311
01312 Etable()->Bottom_up_cr(comp->Enclosed_in_stmt(), comp->Stmt_kid_num(),
01313 comparison_cr->Opnd(1), FALSE,
01314 ETABLE::URGENT_INSERT, 0, OPCODE_UNKNOWN, FALSE);
01315 }
01316
01317 Insert_comp_occurrence(comparison_cr, comp->Enclosed_in_stmt(),
01318 comp->Stmt_kid_num());
01319 } else {
01320
01321 Etable()->Bottom_up_cr(comp->Enclosed_in_stmt(), comp->Stmt_kid_num(),
01322 comparison_cr, FALSE, ETABLE::NOT_URGENT_INS, 0,
01323 OPCODE_UNKNOWN, FALSE);
01324 }
01325
01326 Is_Trace(Trace(),(TFile,"LFTR::Replace_comparison, new comparison:\n"));
01327 Is_Trace_cmd(Trace(),comparison_cr->Print(0,TFile));
01328 }
01329 _num_substitutions++;
01330 }
01331
01332
01333
01334
01335
01336 CODEREP *
01337 LFTR::Find_SR_tempcr(STMTREP *iv_def, CODEREP *temp)
01338 {
01339 Is_True(iv_def != NULL && temp != NULL,
01340 ("LFTR::Find_SR_tempcr2, null iv_def or temp"));
01341
01342
01343 for (STMTREP *tmp_def=iv_def; tmp_def; tmp_def=tmp_def->Next()) {
01344 if (OPERATOR_is_scalar_store (tmp_def->Opr()) &&
01345 tmp_def->Lhs()->Aux_id() == temp->Aux_id())
01346 return tmp_def->Lhs();
01347 }
01348 return NULL;
01349 }
01350
01351
01352
01353
01354
01355
01356 CODEREP *
01357 LFTR::Replace_lftr_var(CODEREP *templt, AUX_ID lftr_var, CODEREP *new_expr)
01358 {
01359 INT32 i;
01360 switch (templt->Kind()) {
01361 case CK_OP:
01362 for (i = 0; i < templt->Kid_count(); i++) {
01363 CODEREP *kid = templt->Opnd(i);
01364 CODEREP *tmp = Replace_lftr_var(kid, lftr_var, new_expr);
01365 if (tmp != NULL && tmp != kid) {
01366 #ifdef KEY // bug 12770
01367 CODEREP *cr = Alloc_stack_cr(0);
01368 if (MTYPE_byte_size(templt->Dtyp()) > MTYPE_byte_size(tmp->Dtyp())) {
01369 cr->Init_expr(OPC_I8I4CVT, tmp);
01370 tmp = Htable()->Rehash(cr);
01371 }
01372 #endif
01373 templt->Set_opnd(i,tmp);
01374 }
01375 }
01376 break;
01377
01378 case CK_VAR:
01379 if (templt->Aux_id() == lftr_var)
01380 return new_expr;
01381 break;
01382
01383 default:
01384 break;
01385 }
01386 return templt;
01387 }
01388
01389
01390
01391
01392
01393
01394 void
01395 LFTR::Remove_comp_occur(EXP_OCCURS *occur)
01396 {
01397 Is_True(Lftr_on(), ("LFTR::Remove_comp_occur called with LFTR off"));
01398 Is_True(Is_comparison(occur->Occurrence()),
01399 ("LFTR::Remove_comp_occur, need a comparison"));
01400 Is_True(occur->Occ_kind() == EXP_OCCURS::OCC_REAL_OCCUR,
01401 ("LFTR::Remove_comp_occur_stmt, occur must be a real occur"));
01402 Is_Trace(Trace(), (TFile,"LFTR::Remove_comp_occur\n"));
01403
01404
01405 AUX_ID lftr_var = Find_lftr_var_id(occur->Occurrence());
01406 if (lftr_var == ILLEGAL_AUX_ID) {
01407 Is_Trace(Trace(),
01408 (TFile,"LFTR::Remove_comp_occur, could not find lftr_var\n"));
01409 return;
01410 }
01411 LFTR_VAR *lftr_var_head = Find_comp_list(lftr_var);
01412
01413
01414 if (lftr_var_head == NULL) {
01415 Is_Trace(Trace(),
01416 (TFile,"LFTR::Remove_comp_occur, could not find lftr_var_head\n"));
01417 return;
01418 }
01419
01420
01421 EXP_OCCURS *comp, *comp_prev = NULL;
01422 EXP_OCCURS_ITER comp_iter;
01423 BOOL found_comp = FALSE, found_stmt = FALSE;
01424 Is_Trace(Trace(), (TFile, " --- checking 0x%p kid %d\n",
01425 occur->Stmt(), occur->Stmt_kid_num()));
01426 Is_Trace_cmd(Trace(), occur->Print(TFile));
01427 Is_Trace(Trace(), (TFile, " in\n"));
01428 Is_Trace_cmd(Trace(), occur->Stmt()->Print(TFile));
01429 FOR_ALL_NODE(comp, comp_iter, Init(lftr_var_head->Occ_list())) {
01430
01431
01432 Is_Trace(Trace(), (TFile, " --- against 0x%p kid %d\n",
01433 comp->Stmt(), comp->Stmt_kid_num()));
01434 Is_Trace_cmd(Trace(), comp->Print(TFile));
01435 Is_Trace(Trace(), (TFile, " in\n"));
01436 Is_Trace_cmd(Trace(), comp->Stmt()->Print(TFile));
01437 if (occur->Occurrence() == comp->Occurrence() &&
01438 occur->Enclosed_in_stmt() == comp->Enclosed_in_stmt()) {
01439 found_stmt = TRUE;
01440 if (occur->Stmt_kid_num() == comp->Stmt_kid_num()) {
01441 Is_Trace(Trace(), (TFile,"LFTR::Remove_comp_occur, removed comp:\n"));
01442 Is_Trace_cmd(Trace(),comp->Occurrence()->Print(0,TFile));
01443 if (comp_prev == NULL)
01444 lftr_var_head->Set_occ_list(comp->Next());
01445 else
01446 comp_prev->Set_Next(comp->Next());
01447 lftr_var_head->Dec_list_size();
01448
01449 Is_True(occur->Mult_real() || !found_comp,
01450 ("LFTR::Remove_comp_occur: Multiple comps in same stmt "
01451 "kid must correspond to Mult_real()"));
01452 found_comp = TRUE;
01453 }
01454 }
01455 else if (found_stmt &&
01456 (occur->Enclosed_in_stmt() != comp->Enclosed_in_stmt() ||
01457 occur->Stmt_kid_num() != comp->Stmt_kid_num())) {
01458
01459
01460 break;
01461 }
01462 comp_prev = comp;
01463 }
01464 }
01465
01466
01467
01468
01469 void
01470 LFTR::Update_comp_occur_stmt(EXP_OCCURS *occur, STMTREP *new_stmt)
01471 {
01472 Is_True(Lftr_on(), ("LFTR::Update_comp_occur_stmt, LFTR must be on"));
01473 Is_True(Is_comparison(occur->Occurrence()),
01474 ("LFTR::Update_comp_occur_stmt, need a comparison"));
01475 Is_True(occur->Occ_kind() == EXP_OCCURS::OCC_REAL_OCCUR,
01476 ("LFTR::Update_comp_occur_stmt, occur must be a real occur"));
01477 Is_Trace(Trace(),(TFile,"LFTR::Update_comp_occur_stmt\n"));
01478
01479
01480 AUX_ID lftr_var = Find_lftr_var_id(occur->Occurrence());
01481 if (lftr_var == ILLEGAL_AUX_ID) {
01482 Is_Trace(Trace(),
01483 (TFile,"LFTR::Update_comp_occur_stmt, could not find lftr_var\n"));
01484 return;
01485 }
01486 LFTR_VAR *lftr_var_head = Find_comp_list(lftr_var);
01487
01488
01489 if (lftr_var_head == NULL) {
01490 Is_Trace(Trace(),
01491 (TFile,"LFTR::Update_comp_occur_stmt, could not find lftr_var_head\n"));
01492 return;
01493 }
01494
01495
01496 EXP_OCCURS *comp, *comp_next, *comp_prev = NULL, *update = NULL;
01497 EXP_OCCURS_ITER comp_iter(lftr_var_head->Occ_list());
01498 for( comp = comp_iter.First(); ! comp_iter.Is_Empty(); comp = comp_next) {
01499 comp_next = comp_iter.Next();
01500
01501 if (update) {
01502 if (comp_next == NULL || !update->Is_DPO_less_than(comp_next)) {
01503 comp->Set_Next(update);
01504 update->Set_Next(comp_next);
01505 break;
01506 }
01507 comp_prev = comp;
01508 }
01509 else if (occur->Occurrence() == comp->Occurrence() &&
01510 occur->Enclosed_in_stmt() == comp->Enclosed_in_stmt()) {
01511 Is_Trace(Trace(),(TFile,"LFTR::Update_comp_occur_stmt, old:\n"));
01512 Is_Trace_cmd(Trace(),comp->Enclosed_in_stmt()->Print(TFile));
01513 comp->Set_enclose_stmt(new_stmt);
01514 comp->Set_stmt_kid_num(1);
01515 Is_Trace(Trace(),(TFile,"new:\n"));
01516 Is_Trace_cmd(Trace(),comp->Enclosed_in_stmt()->Print(TFile));
01517
01518 if (comp_next && !comp->Is_DPO_less_than(comp_next)) {
01519
01520 if (comp_prev == NULL)
01521 lftr_var_head->Set_occ_list(comp_next);
01522 else
01523 comp_prev->Set_Next(comp_next);
01524 update = comp;
01525 update->Set_Next(NULL);
01526 }
01527 else if (comp_prev && comp->Is_DPO_less_than(comp_prev)) {
01528
01529 comp_prev->Set_Next(comp_next);
01530 lftr_var_head->Add_comparison(comp);
01531 }
01532 else
01533 break;
01534 }
01535 else
01536 comp_prev = comp;
01537 }
01538 }
01539
01540
01541
01542
01543 void
01544 LFTR::Print(FILE *fp)
01545 {
01546 fprintf(fp,"%sLFTR::Print\n",DBar);
01547 fprintf(fp,"_trace=%c, _lftr_on=%c, _mem_pool=0x%p, _etable=0x%p\n",
01548 _trace?'T':'F', _lftr_on?'T':'F', &_mem_pool, _etable);
01549 fprintf(fp,"_num_substitutions=%d\n%s",_num_substitutions, DBar);
01550
01551 if (_hash_vec != NULL) {
01552 for (INT32 index=0; index<=_hash_size; index++) {
01553 LFTR_VAR *ltmp = _hash_vec[index];
01554 if (ltmp != NULL) {
01555 fprintf(fp,"_hash_vec[%d]:\n",index);
01556 LFTR_VAR *tmp;
01557 LFTR_VAR_ITER lftr_var_iter(ltmp);
01558 FOR_ALL_NODE(tmp, lftr_var_iter, Init())
01559 tmp->Print(fp);
01560 }
01561 }
01562 fprintf(fp,"%s",DBar);
01563 }
01564 }
01565
01566
01567
01568
01569 void
01570 LFTR_VAR::Print(FILE *fp)
01571 {
01572 fprintf(fp," lftr_var: %d\n",Lftr_var());
01573 EXP_OCCURS *ctmp;
01574 EXP_OCCURS_ITER comp_iter(Occ_list());
01575 FOR_ALL_NODE(ctmp, comp_iter, Init()) {
01576 ctmp->Print(fp);
01577 ctmp->Occurrence()->Print(0,fp);
01578 }
01579 }