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
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 #ifdef USE_PCH
00088 #include "opt_pch.h"
00089 #endif // USE_PCH
00090 #pragma hdrstop
00091
00092
00093 #ifdef _KEEP_RCS_ID
00094 #define opt_ivr_CXX "opt_ivr.cxx"
00095 static char *rcs_id = opt_ivr_CXX"$Revision: 1.19 $";
00096 #endif
00097
00098 #define USE_STANDARD_TYPES
00099
00100 #include "defs.h"
00101 #include "errors.h"
00102 #include "erglob.h"
00103 #include "tracing.h"
00104 #include "cxx_memory.h"
00105 #include "wn.h"
00106 #include "wn_util.h"
00107 #include "region_util.h"
00108
00109 #include "opt_base.h"
00110 #include "opt_bb.h"
00111 #include "bb_node_set.h"
00112 #include "opt_main.h"
00113 #include "opt_ivr.h"
00114 #include "opt_util.h"
00115 #include "opt_wn.h"
00116 #include "opt_mu_chi.h"
00117 #include "opt_fold.h"
00118 #include "stab.h"
00119
00120
00121
00122 inline void
00123 Set_Preg_Name(PREG_NUM preg_num, const char *const name)
00124 {
00125 Is_True(preg_num > Last_Dedicated_Preg_Offset,
00126 ("Set_Preg_Name: Cannot set name of dedicated PREG"));
00127 Set_PREG_name(Preg_Table[preg_num - Last_Dedicated_Preg_Offset], name);
00128 }
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 enum IV_EXPR_FLAGS {
00260 IV_EXPR_NONE = 0,
00261 IV_EXPR_VALID = 1,
00262 };
00263
00264
00265 class IV_EXPR {
00266 INT32 _flags;
00267 BB_LOOP *_loop;
00268 CODEREP *_iv_expr;
00269 CODEREP *_based_iv;
00270 INT64 _step;
00271
00272 BOOL Iv_expr_valid(void) { return _flags & IV_EXPR_VALID; }
00273 BB_LOOP *Loop(void) { return _loop; }
00274 CODEREP *Iv_expr(void) { return _iv_expr; }
00275
00276 void Set_flags(INT32 flags) { _flags = flags; }
00277 void Set_iv_expr_valid(void) { _flags |= IV_EXPR_VALID; }
00278 void Reset_iv_expr_valid(void) { _flags &= ~IV_EXPR_VALID; }
00279 void Set_loop(BB_LOOP *loop) { _loop = loop; }
00280 void Set_iv_expr(CODEREP *iv_expr) { _iv_expr = iv_expr; }
00281 void Set_based_iv(CODEREP *based_iv) { _based_iv = based_iv; }
00282 void Set_step(INT64 step) { _step = step; }
00283
00284 BOOL Eval_to_const(CODEREP *);
00285 INT64 Get_const(CODEREP *);
00286 CODEREP *Find_IV(CODEREP *);
00287 INT64 Find_step(CODEREP *);
00288
00289 public:
00290
00291 IV_EXPR(void) {};
00292 ~IV_EXPR(void) {};
00293
00294 CODEREP *Based_iv(void) { return _based_iv; }
00295 INT64 Step(void) { return _step; }
00296 BOOL Valid_expr(void) { return Iv_expr_valid() && Based_iv() != NULL && Step() != 0; }
00297
00298 void Init(CODEREP *iv_expr, BB_LOOP *loop) {
00299 Set_loop(loop);
00300 Set_iv_expr(iv_expr);
00301 Set_based_iv (NULL);
00302 Set_step(0);
00303
00304
00305
00306 Set_flags(IV_EXPR_VALID);
00307 CODEREP *cr = Find_IV(iv_expr);
00308
00309 if (Iv_expr_valid()) {
00310 Set_based_iv (cr);
00311 Set_step ( Find_step(iv_expr) );
00312 }
00313 }
00314 };
00315
00316
00317
00318
00319 BOOL
00320 IV_EXPR::Eval_to_const(CODEREP *cr)
00321 {
00322 switch (cr->Kind()) {
00323 case CK_LDA:
00324 case CK_VAR:
00325 case CK_IVAR:
00326 return FALSE;
00327
00328 case CK_CONST:
00329 return TRUE;
00330
00331 case CK_OP:
00332 OPERATOR opr = cr->Opr();
00333 switch (opr) {
00334 case OPR_PAREN:
00335 case OPR_NEG:
00336 return Eval_to_const(cr->Opnd(0));
00337
00338 case OPR_ADD:
00339 case OPR_SUB:
00340 case OPR_MPY:
00341 return Eval_to_const(cr->Opnd(0)) && Eval_to_const(cr->Opnd(1));
00342 }
00343
00344 }
00345
00346 return FALSE;
00347 }
00348
00349
00350
00351
00352
00353
00354 CODEREP *
00355 IV_EXPR::Find_IV(CODEREP *iv_expr)
00356 {
00357 switch (iv_expr->Kind()) {
00358 case CK_LDA:
00359 case CK_CONST:
00360 return NULL;
00361
00362 case CK_IVAR:
00363 if (!Loop()->Invariant_cr(iv_expr))
00364 Reset_iv_expr_valid();
00365 return NULL;
00366
00367 case CK_VAR:
00368 if (Loop()->Invariant_cr(iv_expr))
00369 return NULL;
00370 else
00371 return iv_expr;
00372
00373 case CK_OP:
00374 OPERATOR opr = iv_expr->Opr();
00375 switch (opr) {
00376 case OPR_PAREN:
00377 case OPR_NEG:
00378 return Find_IV(iv_expr->Opnd(0));
00379
00380 case OPR_MPY:
00381 {
00382 CODEREP *opnd0_has_iv = Find_IV(iv_expr->Opnd(0));
00383 CODEREP *opnd1_has_iv = Find_IV(iv_expr->Opnd(1));
00384
00385 if (opnd0_has_iv && !opnd1_has_iv && Eval_to_const(iv_expr->Opnd(1)))
00386 return opnd0_has_iv;
00387 if (opnd1_has_iv && !opnd0_has_iv && Eval_to_const(iv_expr->Opnd(0)))
00388 return opnd1_has_iv;
00389
00390 Reset_iv_expr_valid();
00391 return NULL;
00392 }
00393
00394 case OPR_ADD:
00395 case OPR_SUB:
00396 {
00397 CODEREP *opnd0_has_iv = Find_IV(iv_expr->Opnd(0));
00398 CODEREP *opnd1_has_iv = Find_IV(iv_expr->Opnd(1));
00399 if (!opnd0_has_iv && !opnd1_has_iv)
00400 return NULL;
00401 if (opnd0_has_iv && !opnd1_has_iv)
00402 return opnd0_has_iv;
00403 if (opnd1_has_iv && !opnd0_has_iv)
00404 return opnd1_has_iv;
00405 if (opnd0_has_iv && opnd1_has_iv && opnd0_has_iv == opnd1_has_iv)
00406 return opnd0_has_iv;
00407
00408 Reset_iv_expr_valid();
00409 return NULL;
00410 }
00411
00412 default:
00413 if (!Loop()->Invariant_cr(iv_expr))
00414 Reset_iv_expr_valid();
00415 return NULL;
00416
00417 }
00418
00419 }
00420
00421
00422 Reset_iv_expr_valid();
00423 return NULL;
00424 }
00425
00426
00427
00428 INT64
00429 IV_EXPR::Get_const(CODEREP *cr)
00430 {
00431 switch (cr->Kind()) {
00432 case CK_LDA:
00433 case CK_VAR:
00434 case CK_IVAR:
00435 return 0;
00436
00437 case CK_CONST:
00438 return cr->Const_val();
00439
00440 case CK_OP:
00441 OPERATOR opr = cr->Opr();
00442 switch (opr) {
00443 case OPR_PAREN:
00444 return Get_const(cr->Opnd(0));
00445
00446 case OPR_NEG:
00447 return (- Get_const(cr->Opnd(0)));
00448
00449 case OPR_ADD:
00450 return Get_const(cr->Opnd(0)) + Get_const(cr->Opnd(1));
00451
00452 case OPR_SUB:
00453 return Get_const(cr->Opnd(0)) - Get_const(cr->Opnd(1));
00454
00455 case OPR_MPY:
00456 return Get_const(cr->Opnd(0)) * Get_const(cr->Opnd(1));
00457
00458 }
00459
00460 }
00461
00462 Is_True(FALSE, ("Get_const: improper formatted IV expr."));
00463 return 0;
00464 }
00465
00466
00467
00468
00469
00470
00471 INT64
00472 IV_EXPR::Find_step(CODEREP *iv_expr)
00473 {
00474 INT32 kid0;
00475 INT32 kid1;
00476 switch (iv_expr->Kind()) {
00477 case CK_LDA:
00478 case CK_CONST:
00479 return 0;
00480
00481 case CK_IVAR:
00482 Is_True(Loop()->Invariant_cr(iv_expr),
00483 ("Find_step: Improper formatted IV EXPR."));
00484 return 0;
00485
00486 case CK_VAR:
00487 if (iv_expr == Based_iv())
00488 return 1;
00489 else {
00490 Is_True(Loop()->Invariant_cr(iv_expr),
00491 ("Find_step: Improper formatted IV EXPR."));
00492 return 0;
00493 }
00494
00495 case CK_OP:
00496 OPERATOR opr = iv_expr->Opr();
00497 switch (opr) {
00498 case OPR_PAREN:
00499 return Find_step(iv_expr->Opnd(0));
00500
00501 case OPR_NEG:
00502 return (- Find_step(iv_expr->Opnd(0)));
00503
00504 case OPR_ADD:
00505 kid0 = Find_step(iv_expr->Opnd(0));
00506 kid1 = Find_step(iv_expr->Opnd(1));
00507 return kid0 + kid1;
00508
00509 case OPR_SUB:
00510 kid0 = Find_step(iv_expr->Opnd(0));
00511 kid1 = Find_step(iv_expr->Opnd(1));
00512 return kid0 - kid1;
00513
00514 case OPR_MPY:
00515 kid0 = Find_step(iv_expr->Opnd(0));
00516 kid1 = Find_step(iv_expr->Opnd(1));
00517 if (kid0 != 0 && kid1 == 0)
00518 return kid0 * Get_const(iv_expr->Opnd(1));
00519 if (kid1 != 0 && kid0 == 0)
00520 return kid1 * Get_const(iv_expr->Opnd(0));
00521 if (kid0 == 0 && kid1 == 0)
00522 return 0;
00523
00524 Is_True(FALSE, ("Find_step: Improper formatted IV EXPR."));
00525 return 0;
00526
00527 default:
00528 Is_True(Loop()->Invariant_cr(iv_expr),
00529 ("Find_step: Improper formatted IV EXPR."));
00530 return 0;
00531 }
00532 }
00533
00534 Is_True(FALSE, ("Find_step: Improper formatted IV EXPR."));
00535 return 0;
00536 }
00537
00538
00539
00540
00541
00542
00543
00544
00545 void
00546 IVR::Reset_dont_prop(CODEREP *cr, const BB_LOOP *loop)
00547 {
00548 switch (cr->Kind()) {
00549 case CK_LDA:
00550 case CK_CONST:
00551 case CK_RCONST:
00552 case CK_IVAR:
00553 return;
00554 case CK_VAR:
00555 {
00556
00557 if (cr->Is_var_volatile())
00558 return;
00559
00560
00561 ST *s = Opt_stab()->St(cr->Aux_id());
00562 if ((ST_class(s) == CLASS_PREG && Preg_Is_Dedicated(cr->Offset())))
00563 return;
00564
00565 if (loop->Invariant_cr(cr))
00566 return;
00567
00568 cr->Reset_flag(CF_DONT_PROP);
00569 if (cr->Defstmt() != NULL &&
00570 !cr->Is_flag_set((CR_FLAG)(CF_DEF_BY_PHI|CF_DEF_BY_CHI)))
00571 if (cr->Defstmt()->Rhs()->Propagatable_for_ivr(Opt_stab()))
00572 Reset_dont_prop(cr->Defstmt()->Rhs(), loop);
00573
00574 return;
00575 }
00576
00577 case CK_OP:
00578 for (INT32 i = 0; i < cr->Kid_count(); i++)
00579 Reset_dont_prop( cr->Opnd(i), loop);
00580 return;
00581 }
00582 return;
00583 }
00584
00585
00586
00587
00588
00589
00590
00591 CODEREP *
00592 CODEMAP::Expand_expr(CODEREP *cr, const BB_LOOP *loop, INT32 *limit)
00593 {
00594 switch (cr->Kind()) {
00595 case CK_LDA:
00596 case CK_CONST:
00597 case CK_RCONST:
00598 case CK_IVAR:
00599 return NULL;
00600 case CK_VAR:
00601 if (*limit > 0) {
00602
00603 if (cr->Is_var_volatile())
00604 return NULL;
00605
00606
00607 ST *s = sym->St(cr->Aux_id());
00608 if ((ST_class(s) == CLASS_PREG && Preg_Is_Dedicated(cr->Offset())))
00609 return NULL;
00610
00611 if (loop->Invariant_cr(cr))
00612 return NULL;
00613
00614 if (cr->Is_flag_set(CF_DEF_BY_PHI)) {
00615 PHI_NODE *phi = cr->Defphi();
00616 BB_NODE *bb = cr->Defbb();
00617 CODEREP *identical_rhs = NULL;
00618 BB_NODE *pred; BB_LIST_ITER bb_iter;
00619 FOR_ALL_ELEM (pred, bb_iter, Init(bb->Pred())) {
00620 CODEREP *tmp = phi->OPND(bb_iter.Idx());
00621 STMTREP *defstmt = tmp->Get_defstmt();
00622 if (defstmt == NULL || ! OPERATOR_is_scalar_store (defstmt->Opr()) ||
00623 tmp->Is_flag_set(CF_DEF_BY_CHI)) {
00624 identical_rhs = NULL;
00625 break;
00626 }
00627 if (identical_rhs == NULL)
00628 if (defstmt->Rhs()->Propagatable_for_ivr(Opt_stab()))
00629 identical_rhs = defstmt->Rhs();
00630 else
00631 break;
00632 else if (identical_rhs != defstmt->Rhs()) {
00633 identical_rhs = NULL;
00634 break;
00635 }
00636 }
00637 if (identical_rhs != NULL) {
00638 CODEREP *expr = Expand_expr(identical_rhs, loop, limit);
00639 --(*limit);
00640 if (expr)
00641 return expr;
00642 else
00643 return identical_rhs;
00644 }
00645 } else if (cr->Defstmt() != NULL && !cr->Is_flag_set(CF_DEF_BY_CHI)) {
00646 if (cr->Defstmt()->Rhs()->Propagatable_for_ivr(Opt_stab())) {
00647 CODEREP *expr = Expand_expr(cr->Defstmt()->Rhs(), loop, limit);
00648 --(*limit);
00649 if (expr)
00650 return expr;
00651 else
00652 return cr->Defstmt()->Rhs();
00653 }
00654 }
00655 }
00656 return NULL;
00657
00658 case CK_OP:
00659 {
00660 CODEREP *newcr = Alloc_stack_cr(cr->Kid_count());
00661 BOOL need_rehash = FALSE;
00662 CODEREP *expr;
00663 FOLD ftmp;
00664 newcr->Copy(*cr);
00665 for (INT32 i = 0; i < cr->Kid_count(); i++) {
00666 expr = Expand_expr( cr->Opnd(i), loop, limit);
00667 if (expr) {
00668 need_rehash = TRUE;
00669 newcr->Set_opnd(i, expr);
00670 } else
00671 newcr->Set_opnd(i, cr->Opnd(i));
00672 }
00673 if (need_rehash) {
00674 expr = ftmp.Fold_Expr(newcr);
00675 if (expr == NULL)
00676 expr = Rehash(newcr);
00677 return expr;
00678 }
00679 }
00680 return NULL;
00681 }
00682 return NULL;
00683 }
00684
00685
00686
00687
00688 static CODEREP *
00689 Find_cur_cr(IDTYPE aux_id,
00690 const BB_NODE *start ,
00691 const BB_NODE *stop )
00692 {
00693 PHI_NODE *phi;
00694 PHI_LIST_ITER phi_iter;
00695 BB_NODE *stop2 = stop->Idom();
00696 for (const BB_NODE *bb=start; bb!=NULL && bb!=stop2; bb=bb->Idom()) {
00697 STMTREP *stmt;
00698 STMTREP_ITER stmt_iter(((BB_NODE *)bb)->Stmtlist());
00699 FOR_ALL_NODE_REVERSE(stmt, stmt_iter, Init()) {
00700 if (stmt->Has_chi()) {
00701 CHI_LIST_ITER chi_iter;
00702 CHI_NODE *cnode;
00703 CHI_LIST *chi_list = stmt->Chi_list();
00704 FOR_ALL_NODE( cnode, chi_iter, Init(chi_list)) {
00705 if (cnode->Aux_id() == aux_id)
00706 return cnode->RESULT();
00707 }
00708 }
00709 if (OPERATOR_is_scalar_store (stmt->Opr()) &&
00710 stmt->Lhs()->Aux_id() == aux_id)
00711 return stmt->Lhs();
00712 }
00713 FOR_ALL_ELEM (phi, phi_iter, Init(bb->Phi_list())) {
00714 if (phi->Aux_id() == aux_id)
00715 return phi->RESULT();
00716 }
00717 }
00718 return NULL;
00719 }
00720
00721
00722
00723
00724 BOOL
00725 CODEREP::Propagatable_along_path(const BB_NODE *dest ,
00726 const BB_NODE *src ) const
00727 {
00728 CODEREP *cur_cr;
00729
00730 switch (Kind()) {
00731 case CK_LDA:
00732 case CK_CONST:
00733 case CK_RCONST:
00734 return TRUE;
00735 case CK_VAR:
00736 cur_cr = Find_cur_cr(Aux_id(), dest, src);
00737 return (cur_cr == NULL || cur_cr == this);
00738 case CK_IVAR:
00739 return FALSE;
00740 case CK_OP:
00741 for (INT32 i = 0; i < Kid_count(); i++)
00742 if (! Opnd(i)->Propagatable_along_path(dest, src))
00743 return FALSE;
00744 if (Opr() == OPR_INTRINSIC_OP
00745 #ifdef KEY
00746 || Opr() == OPR_PURE_CALL_OP
00747 #endif
00748 )
00749 return FALSE;
00750 return TRUE;
00751 }
00752 return FALSE;
00753 }
00754
00755
00756
00757
00758 BOOL
00759 CODEREP::Propagatable_into_loop(const BB_LOOP *loop) const
00760 {
00761 switch (Kind()) {
00762 case CK_LDA:
00763 case CK_CONST:
00764 case CK_RCONST:
00765 return TRUE;
00766 case CK_VAR:
00767
00768 { PHI_LIST_ITER phi_iter;
00769 PHI_NODE *phi;
00770 FOR_ALL_ELEM (phi, phi_iter, Init(loop->Header()->Phi_list())) {
00771 if (phi->Aux_id() == Aux_id())
00772 return FALSE;
00773 }
00774 return TRUE;
00775 }
00776 case CK_IVAR:
00777 return FALSE;
00778 case CK_OP:
00779 for (INT32 i = 0; i < Kid_count(); i++)
00780 if (! Opnd(i)->Propagatable_into_loop(loop))
00781 return FALSE;
00782 if (Opr() == OPR_INTRINSIC_OP
00783 #ifdef KEY
00784 || Opr() == OPR_PURE_CALL_OP
00785 #endif
00786 #if defined(TARG_IA32) || defined(TARG_X8664)
00787 || Opr() == OPR_SELECT
00788 #endif
00789 )
00790 return FALSE;
00791 return TRUE;
00792 }
00793 return FALSE;
00794 }
00795
00796
00797 BOOL
00798 CODEREP::Propagatable_for_ivr(OPT_STAB *sym) const
00799 {
00800 switch (kind) {
00801 case CK_LDA:
00802 case CK_CONST:
00803 case CK_RCONST:
00804 return TRUE;
00805 case CK_VAR:
00806 {
00807
00808 if (Is_var_volatile())
00809 return FALSE;
00810
00811 ST *s = sym->St(Aux_id());
00812 if ((ST_class(s) == CLASS_PREG && Preg_Is_Dedicated(Offset())))
00813 return FALSE;
00814 return TRUE;
00815 }
00816 case CK_IVAR: return FALSE;
00817 case CK_OP:
00818 if (OPCODE_is_volatile(Op()))
00819 return NOT_PROPAGATABLE;
00820 for (INT32 i = 0; i < Kid_count(); i++) {
00821 if (! Opnd(i)->Propagatable_for_ivr(sym))
00822 return FALSE;
00823 }
00824 if (! Op_can_be_propagated(Op(), sym->Phase()))
00825 return FALSE;
00826
00827
00828 if (Opr() == OPR_INTRINSIC_OP
00829 #ifdef KEY
00830 || Opr() == OPR_PURE_CALL_OP
00831 #endif
00832 )
00833 return FALSE;
00834 return TRUE;
00835 }
00836 return FALSE;
00837 }
00838
00839
00840
00841
00842
00843
00844 CODEREP *
00845 CODEMAP::Convert_to_loop_invar(CODEREP *cr, BB_LOOP *loop)
00846 {
00847 if (cr->Kind() == CK_VAR && cr->Is_flag_set(CF_IS_ZERO_VERSION))
00848 return NULL;
00849
00850 if (cr->Kind() == CK_LDA ||
00851 cr->Kind() == CK_CONST ||
00852 cr->Kind() == CK_RCONST)
00853 return cr;
00854
00855 if (loop->Invariant_cr(cr) &&
00856 cr->Propagatable_for_ivr(Opt_stab()) &&
00857 cr->Propagatable_into_loop(loop))
00858 return cr;
00859
00860 if (cr->Kind() == CK_VAR &&
00861 !cr->Is_flag_set((CR_FLAG)(CF_DEF_BY_PHI|CF_DEF_BY_CHI)) &&
00862 cr->Defstmt() != NULL) {
00863 CODEREP *new_expr = cr->Defstmt()->Rhs();
00864 if (new_expr->Propagatable_for_ivr(Opt_stab()) &&
00865 new_expr->Propagatable_into_loop(loop) &&
00866 new_expr->Propagatable_along_path(loop->Header()->Idom(),
00867 cr->Defbb()->Idom()))
00868 return new_expr;
00869 }
00870
00871
00872 MTYPE temp_type;
00873 #ifdef KEY
00874 MTYPE temp_rtype;
00875 #endif
00876 if ( cr->Kind() == CK_VAR ) {
00877
00878 temp_type = TY_mtype(ST_type(MTYPE_To_PREG(cr->Dsctyp())));
00879 #ifdef KEY
00880 temp_rtype = TY_mtype(ST_type(MTYPE_To_PREG(cr->Dtyp())));
00881 #endif
00882 #ifdef KEY // bug 11467
00883 if (temp_type == MTYPE_BS)
00884 temp_type = temp_rtype;
00885 #endif
00886 }
00887 else {
00888 temp_type = cr->Dtyp();
00889 #ifdef KEY
00890 temp_rtype = cr->Dtyp();
00891 #endif
00892 }
00893 #ifdef KEY
00894
00895 static INT Temp_Index = 0;
00896 UINT len = strlen("_temp_") + 17;
00897 char *new_str = (char *) alloca (len);
00898 sprintf(new_str, "%s%d", "_temp_", Temp_Index++);
00899 IDTYPE new_temp = Opt_stab()->Create_preg( temp_type, new_str );
00900 #else
00901 IDTYPE new_temp = Opt_stab()->Create_preg( temp_type, new_str );
00902 #endif
00903 Add_new_auxid_to_entry_chis(new_temp, Cfg(), this, Opt_stab());
00904 #ifdef KEY
00905 CODEREP *new_cr = Add_def(new_temp, 1, NULL, temp_rtype, temp_type,
00906 Opt_stab()->Aux_stab_entry(new_temp)->St_ofst(),
00907 MTYPE_To_TY(cr->Dtyp()), 0, TRUE);
00908 #else
00909 CODEREP *new_cr = Add_def(new_temp, 1, NULL, temp_type, temp_type,
00910 Opt_stab()->Aux_stab_entry(new_temp)->St_ofst(),
00911 MTYPE_To_TY(cr->Dtyp()), 0, TRUE);
00912 #endif
00913
00914 Insert_var_phi(new_cr, loop->Preheader());
00915
00916
00917
00918 if (cr->Kind() == CK_VAR &&
00919 !cr->Is_flag_set((CR_FLAG)(CF_DEF_BY_PHI|CF_DEF_BY_CHI)) &&
00920 !cr->Is_var_volatile() &&
00921 cr->Defstmt() != NULL &&
00922 cr->Defstmt()->Bb() == loop->Preheader() &&
00923 cr->Defstmt()->Rhs()->Propagatable_for_ivr(Opt_stab())) {
00924
00925 STMTREP *stmt = cr->Defstmt()->Rhs()->Create_cpstmt(new_cr,
00926 Mem_pool());
00927 loop->Preheader()->Insert_stmtrep_before(stmt, cr->Defstmt());
00928
00929 } else {
00930 STMTREP *stmt = cr->Create_cpstmt(new_cr, Mem_pool());
00931 loop->Preheader()->Append_stmtrep(stmt);
00932 }
00933
00934 return new_cr;
00935 }
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946 CODEREP*
00947 IVR::Generate_step(CODEREP *nv, CODEREP *iv) const
00948 {
00949 CODEREP *delta = NULL;
00950 MTYPE dtype = nv->Dtyp();
00951
00952
00953 if (nv->Kind() == CK_OP) {
00954 if (nv->Opr() == OPR_ADD) {
00955 for (INT i = 0; i < nv->Kid_count(); i++)
00956 if (nv->Get_opnd(i) == iv) {
00957 delta = (i == 0) ? nv->Get_opnd(1) : nv->Get_opnd(0);
00958 break;
00959 }
00960 } else if (nv->Opr() == OPR_SUB &&
00961 nv->Get_opnd(0) == iv) {
00962 if (nv->Get_opnd(1)->Kind() == CK_CONST) {
00963 delta = Htable()->Add_const(dtype, - nv->Get_opnd(1)->Const_val());
00964 } else {
00965 CODEREP *zero = Htable()->Add_const(dtype, 0);
00966 CODEREP *opnd1 = nv->Get_opnd(1);
00967
00968
00969 delta = Htable()->Add_bin_node_and_fold(nv->Op(), zero, opnd1);
00970 }
00971 }
00972 }
00973
00974 #if 0
00975 Disable this temp because iv has no type! Bugs in htable?
00976
00977
00978 if (delta == NULL && MTYPE_is_integral(nv->Dtyp())) {
00979 OPCODE subop = OPCODE_make_op(OPR_SUB, dtype, MTYPE_V);
00980 delta = Htable()->Add_bin_node_and_fold(subop,
00981 nv->Insert_CVTL(dtype,Htable()),
00982 iv);
00983 }
00984 #endif
00985
00986
00987
00988 if (delta && delta->Contains(iv))
00989 return NULL;
00990
00991 return delta;
00992 }
00993
00994 #define IS_MP_LOOP(loop) (loop->Is_flag_set(LOOP_IS_MP) || loop->Is_flag_set(LOOP_IS_PDO))
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009 void
01010 IVR::Ident_all_iv_cands(const BB_LOOP *loop, const BB_NODE *bb)
01011 {
01012 BOOL is_mp_loop = IS_MP_LOOP(loop);
01013
01014 if (bb->Pred()->Len() != 2) return;
01015
01016 #ifdef KEY
01017 #ifdef Is_True_On
01018 static INT32 ivr_cand_idx = 0;
01019 #endif
01020 #endif
01021
01022 PHI_LIST_ITER phi_iter;
01023 PHI_NODE *phi;
01024 FOR_ALL_ELEM (phi, phi_iter, Init(bb->Phi_list())) {
01025 if (! phi->Live()) continue;
01026 CODEREP *res = phi->RESULT();
01027
01028
01029 if (res->Kind() != CK_VAR) continue;
01030
01031
01032 if (is_mp_loop) {
01033 AUX_STAB_ENTRY *sym = Opt_stab()->Aux_stab_entry(res->Aux_id());
01034 if (sym->Mp_reduction()) continue;
01035 }
01036
01037 if (res->Is_flag_set(CF_IS_ZERO_VERSION)) {
01038 Warn_todo("IVR: deal with zero version as initial value.");
01039 continue;
01040 }
01041
01042 BB_NODE *pred;
01043 BB_LIST_ITER bb_iter;
01044 FOR_ALL_ELEM (pred, bb_iter, Init(bb->Pred())) {
01045
01046
01047 CODEREP *incr = phi->OPND(bb_iter.Idx());
01048 if (incr->Is_flag_set(CF_IS_ZERO_VERSION)) continue;
01049
01050
01051 if (incr->Is_flag_set(CF_DEF_BY_CHI))
01052 continue;
01053
01054
01055
01056 if (!MTYPE_is_integral(incr->Dtyp())) continue;
01057
01058
01059 if (loop->Invariant_cr(incr)) continue;
01060
01061
01062
01063
01064 #ifdef KEY
01065
01066 if (!incr->Is_flag_set(CF_DEF_BY_PHI) && incr->Defstmt() &&
01067 incr->Defstmt()->Volatile_stmt()) break;
01068 #else
01069 if (!incr->Is_flag_set(CF_DEF_BY_PHI) &&
01070 incr->Defstmt()->Volatile_stmt()) break;
01071 #endif
01072
01073
01074 INT32 limit = WOPT_Enable_IVR_Expand_Limit;
01075 CODEREP *expr = Htable()->Expand_expr(incr, loop, &limit);
01076 if (expr == NULL) expr = incr;
01077
01078
01079 CODEREP *step = Generate_step(expr, res);
01080
01081 if (step == NULL || !loop->Invariant_cr(step)) break;
01082
01083 CODEREP *init = (bb_iter.Idx() == 0) ? phi->OPND(1) : phi->OPND(0);
01084
01085 if (init->Is_flag_set(CF_IS_ZERO_VERSION)) break;
01086
01087
01088 if (init->Defstmt() && init->Defstmt()->Volatile_stmt()) break;
01089
01090
01091 MTYPE dtype;
01092 if (incr->Defstmt())
01093 dtype = incr->Defstmt()->Rhs()->Dtyp();
01094 else
01095 dtype = incr->Defphi()->OPND(0)->Defstmt()->Rhs()->Dtyp();
01096
01097
01098
01099
01100 if (init->Dsctyp() != MTYPE_UNKNOWN &&
01101 MTYPE_size_min(init->Dsctyp()) != MTYPE_size_min(incr->Dsctyp()) )
01102 break;
01103 init = init->Var_type_conversion(Htable(), incr->Dtyp(),
01104 incr->Dsctyp(), incr->Lod_ty(),
01105 incr->Field_id());
01106
01107 IV_CAND *new_cand =
01108 CXX_NEW(IV_CAND(phi, init, incr, step, dtype), Mem_pool());
01109 #ifdef KEY
01110 #ifdef Is_True_On
01111 if (WOPT_Enable_Ivr_Cand_Limit != -1 && ivr_cand_idx >= WOPT_Enable_Ivr_Cand_Limit)
01112 break;
01113 ivr_cand_idx++;
01114 #endif
01115 #endif
01116 iv_cand_container.push_back(new_cand);
01117 break;
01118 }
01119 }
01120 if (_trace)
01121 Print_all_iv_cand(TFile);
01122 }
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139 BOOL
01140 IVR::Satisfy_primary_IV(const IV_CAND *iv_cand, BOOL must_be_I4) const
01141 {
01142
01143 if (iv_cand->Init_value() == NULL)
01144 return FALSE;
01145
01146 AUX_STAB_ENTRY *psym =
01147 Opt_stab()->Aux_stab_entry(iv_cand->Var()->Aux_id());
01148 if (psym->Byte_size() < 4) {
01149 if (psym->St() == NULL || ST_sclass(psym->St()) != SCLASS_REG)
01150 return FALSE;
01151 }
01152 if (iv_cand->Step_value()->Kind() != CK_CONST)
01153 return FALSE;
01154 if (iv_cand->Step_value()->Const_val() != 1)
01155 return FALSE;
01156
01157
01158
01159
01160 if (iv_cand->Dtype() != MTYPE_I4)
01161 if (must_be_I4)
01162 return FALSE;
01163 else if (iv_cand->Dtype() != MTYPE_I8)
01164 return FALSE;
01165
01166 return TRUE;
01167 }
01168
01169
01170 const INT32 MIN_SCORE = -10000;
01171
01172
01173
01174
01175
01176 static INT32
01177 Init_expr_cost(CODEREP *cr)
01178 {
01179 if (cr == NULL) return -MIN_SCORE;
01180
01181 switch (cr->Kind()) {
01182 case CK_VAR:
01183 return 2;
01184 case CK_CONST:
01185 if (cr->Const_val() == 0)
01186 return 0;
01187 else
01188 return 1;
01189 case CK_IVAR:
01190 return -MIN_SCORE;
01191 case CK_OP:
01192 {
01193 OPERATOR opr = cr->Opr();
01194 if (opr == OPR_ADD || opr == OPR_SUB)
01195 return Init_expr_cost(cr->Opnd(0)) + Init_expr_cost(cr->Opnd(1));
01196 else if (opr == OPR_NEG)
01197 return Init_expr_cost(cr->Opnd(0));
01198 else
01199 return -MIN_SCORE;
01200 }
01201 }
01202 return -MIN_SCORE;
01203 }
01204
01205
01206 static INT32
01207 Primary_IV_preference(IV_CAND *iv, OPT_STAB *opt_stab)
01208 {
01209 AUX_ID aux_id = iv->Var()->Aux_id();
01210 AUX_STAB_ENTRY *psym = opt_stab->Aux_stab_entry(aux_id);
01211 INT32 score = 1;
01212
01213 #if 0 // IRM no longer supported
01214 if (psym->Irm_generated())
01215 score += 1000;
01216 #endif
01217
01218 if (!psym->Points_to()->No_alias())
01219 score += 100;
01220
01221 if (ST_sclass(psym->St()) != SCLASS_REG)
01222 score += 10;
01223
01224 score -= Init_expr_cost(iv->Init_value());
01225
01226 return score > MIN_SCORE ? score : MIN_SCORE;
01227 }
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242 IV_CAND*
01243 IVR::Choose_primary_IV(const BB_LOOP *loop)
01244 {
01245 WN *index = loop->Index();
01246
01247 vector<IV_CAND*>::iterator iv_cand_iter;
01248
01249 if (Phase() != MAINOPT_PHASE) {
01250
01251 if (index != NULL) {
01252
01253
01254 for (iv_cand_iter = iv_cand_container.begin();
01255 iv_cand_iter != iv_cand_container.end();
01256 iv_cand_iter++) {
01257 IV_CAND *cur_iv = *iv_cand_iter;
01258 AUX_ID cur_aux_id = cur_iv->Var()->Aux_id();
01259 if (Opt_stab()->St(cur_aux_id) == WN_sym(index) &&
01260 Opt_stab()->St_ofst(cur_aux_id) == WN_offset(index) &&
01261 Satisfy_primary_IV(cur_iv, FALSE)) {
01262 cur_iv->Set_is_primary();
01263 return cur_iv;
01264 }
01265 }
01266 return NULL;
01267 } else {
01268
01269 STMTREP *stmt = loop->End()->Last_stmtrep();
01270 if (stmt == NULL || stmt->Rhs() == NULL || stmt->Rhs()->Kind() != CK_OP)
01271 return NULL;
01272
01273 const OPCODE test_opc = stmt->Rhs()->Op();
01274 MTYPE mtype = MTYPE_I4;
01275 if (OPCODE_is_compare(test_opc) &&
01276 MTYPE_size_min(OPCODE_desc(test_opc)) > 32) {
01277 mtype = MTYPE_I8;
01278 }
01279
01280 IDTYPE new_temp = Opt_stab()->Create_preg( mtype, "whiledo_var" );
01281
01282 #ifdef KEY // bug 5778
01283 if (ST_class(Opt_stab()->St(new_temp)) != CLASS_PREG &&
01284 Phase() != MAINOPT_PHASE && loop->Body()->MP_region()) {
01285
01286 BB_NODE *regionbb = loop->Body();
01287 while (regionbb != NULL && regionbb->Kind() != BB_REGIONSTART)
01288 regionbb = Cfg()->Find_enclosing_parallel_region_bb(regionbb);
01289 if (regionbb != NULL) {
01290 WN *pragmawn = WN_CreatePragma(WN_PRAGMA_LOCAL,
01291 Opt_stab()->St(new_temp), 0, 0);
01292 STMTREP *pragmastmt = regionbb->Add_stmtnode(pragmawn,
01293 Htable()->Mem_pool());
01294 pragmastmt->Set_orig_wn(pragmawn);
01295 }
01296 }
01297 #endif
01298
01299 Add_new_auxid_to_entry_chis(new_temp, Cfg(), Htable(), Opt_stab());
01300
01301 CODEREP *init_cr = Htable()->Add_def(new_temp, 1, NULL, mtype, mtype,
01302 Opt_stab()->Aux_stab_entry(new_temp)->St_ofst(),
01303 MTYPE_To_TY(mtype), 0, TRUE);
01304
01305 CODEREP *phi_cr = Htable()->Add_def(new_temp, 2, NULL, mtype, mtype,
01306 Opt_stab()->Aux_stab_entry(new_temp)->St_ofst(),
01307 MTYPE_To_TY(mtype), 0, TRUE);
01308
01309 CODEREP *incr_cr = Htable()->Add_def(new_temp, 3, NULL, mtype, mtype,
01310 Opt_stab()->Aux_stab_entry(new_temp)->St_ofst(),
01311 MTYPE_To_TY(mtype), 0, TRUE);
01312
01313 PHI_NODE *phi = loop->Header()->Phi_list()->
01314 New_phi_node(new_temp, Htable()->Ssa()->Mem_pool(), loop->Header());
01315
01316 phi_cr->Set_flag(CF_DEF_BY_PHI);
01317 phi_cr->Set_defphi(phi);
01318 phi->Reset_dse_dead();
01319 phi->Reset_dce_dead();
01320 phi->Set_res_is_cr();
01321 phi->Set_live();
01322 phi->Set_result(phi_cr);
01323 phi->Set_incomplete();
01324
01325 CODEREP *init_value = Htable()->Add_const(mtype, 0);
01326 STMTREP *init_stmt = init_value->Create_cpstmt(init_cr, Htable()->Mem_pool());
01327 Loop()->Preheader()->Append_stmtrep(init_stmt);
01328 init_stmt->Set_bb(Loop()->Preheader());
01329
01330 OPCODE addop = OPCODE_make_op(OPR_ADD, mtype, MTYPE_V);
01331 CODEREP *step = Htable()->Add_const(mtype, 1);
01332 CODEREP *incr_rhs = Htable()->Add_bin_node_and_fold(addop, phi_cr, step);
01333
01334 STMTREP *incr_stmt =
01335 incr_rhs->Create_cpstmt(incr_cr, Htable()->Mem_pool());
01336
01337 # ifdef KEY
01338 Loop()->Loopback()->Append_stmt_before_branch(incr_stmt);
01339 # else
01340 Loop()->Loopback()->Append_stmtrep(incr_stmt);
01341 # endif
01342 incr_stmt->Set_bb(Loop()->Loopback());
01343
01344 Htable()->Enter_var_phi_hash(phi);
01345 Htable()->Insert_var_phi(phi->RESULT(), phi->Bb());
01346 Htable()->Insert_var_phi(incr_stmt->Lhs(), incr_stmt->Bb());
01347 Htable()->Insert_var_phi(init_stmt->Lhs(), init_stmt->Bb());
01348
01349 phi->Set_opnd(Loop()->Preheader_pred_num(), init_cr);
01350 phi->Set_opnd(Loop()->Loopback_pred_num(), incr_cr);
01351
01352 IV_CAND *new_cand =
01353 CXX_NEW(IV_CAND(phi, init_cr, incr_cr, step, mtype), Mem_pool());
01354 new_cand->Set_is_primary();
01355 new_cand->Set_init_value( init_value );
01356
01357 ivr_generated_primary = TRUE;
01358
01359 iv_cand_container.push_back(new_cand);
01360
01361 if (_trace) {
01362 fprintf(TFile, "IVR: generate primary IV with aux-id %d\n", new_temp);
01363 fprintf(TFile, "IVR: insert phi at BB%d, init at BB%d, incr at BB%d\n",
01364 phi->Bb()->Id(), init_stmt->Bb()->Id(), incr_stmt->Bb()->Id());
01365 }
01366
01367 return new_cand;
01368 }
01369
01370 } else {
01371
01372
01373
01374 INT32 max_score = MIN_SCORE - 1;
01375 IV_CAND *selected_iv = NULL;
01376
01377 for (iv_cand_iter = iv_cand_container.begin();
01378 iv_cand_iter != iv_cand_container.end();
01379 iv_cand_iter++) {
01380 IV_CAND *cur_iv = *iv_cand_iter;
01381 if (Satisfy_primary_IV(cur_iv, TRUE)) {
01382 INT32 score = Primary_IV_preference(cur_iv, Opt_stab());
01383 if (score > max_score) {
01384 max_score = score;
01385 selected_iv = cur_iv;
01386 }
01387 }
01388 }
01389
01390 if (selected_iv != NULL)
01391 return selected_iv;
01392
01393 if (WOPT_Enable_I8_Primary_IV) {
01394 max_score = MIN_SCORE - 1;
01395 for (iv_cand_iter = iv_cand_container.begin();
01396 iv_cand_iter != iv_cand_container.end();
01397 iv_cand_iter++) {
01398 IV_CAND *cur_iv = *iv_cand_iter;
01399 if (Satisfy_primary_IV(cur_iv, FALSE)) {
01400 INT32 score = Primary_IV_preference(cur_iv, Opt_stab());
01401 if (score > max_score) {
01402 max_score = score;
01403 selected_iv = cur_iv;
01404 }
01405 }
01406 }
01407 }
01408
01409 return selected_iv;
01410 }
01411 }
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423 CODEREP *
01424 IVR::Replace_IV_with_invar(CODEREP *iv_expr,
01425 CODEREP *based_iv,
01426 CODEREP *replacement)
01427 {
01428 CODEREP *kid0;
01429 CODEREP *kid1;
01430 switch (iv_expr->Kind()) {
01431 case CK_LDA:
01432 case CK_CONST:
01433 return NULL;
01434
01435 case CK_VAR:
01436 if (iv_expr == based_iv)
01437 return replacement;
01438 else
01439 return NULL;
01440
01441 case CK_OP:
01442 switch (iv_expr->Opr()) {
01443 case OPR_PAREN:
01444 case OPR_NEG:
01445 kid0 = Replace_IV_with_invar(iv_expr->Opnd(0), based_iv, replacement);
01446 if (kid0 != NULL)
01447 return Htable()->Add_unary_node(iv_expr->Op(), kid0);
01448 return NULL;
01449
01450 case OPR_ADD:
01451 case OPR_SUB:
01452 case OPR_MPY:
01453 kid0 = Replace_IV_with_invar(iv_expr->Opnd(0), based_iv, replacement);
01454 kid1 = Replace_IV_with_invar(iv_expr->Opnd(1), based_iv, replacement);
01455 if (!kid0 && !kid1)
01456 return NULL;
01457 if (kid0 && !kid1)
01458 return Htable()->Add_bin_node_and_fold(iv_expr->Op(), kid0,
01459 iv_expr->Opnd(1));
01460 if (kid1 && !kid0)
01461 return Htable()->Add_bin_node_and_fold(iv_expr->Op(),
01462 iv_expr->Opnd(0),
01463 kid1);
01464
01465 if (iv_expr->Opr() == OPR_MPY) {
01466 Is_True(FALSE,
01467 ("Replace_IV_with_invar: improper formatted IV expr."));
01468 }
01469
01470 return Htable()->Add_bin_node_and_fold(iv_expr->Op(), kid0, kid1);
01471
01472 default:
01473 return NULL;
01474 }
01475
01476 case CK_IVAR:
01477 return NULL;
01478
01479 }
01480
01481 Is_True(FALSE, ("Replace_IV_with_invar: improper formatted IV expr."));
01482 return NULL;
01483 }
01484
01485
01486
01487
01488
01489
01490
01491
01492 CODEREP *
01493 IVR::Compute_trip_count(const OPCODE cmp_opc,
01494 BB_LOOP *loop,
01495 CODEREP *bound,
01496 CODEREP *var,
01497 CODEREP *init,
01498 CODEREP *step,
01499 CODEREP *iv_expr,
01500 CODEREP *based_iv,
01501 INT64 new_step,
01502 BOOL test_at_entry,
01503 STMTREP *cmp_stmt,
01504 BOOL swapped,
01505 IV_CAND *primary_cand)
01506 {
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529 BOOL perform_slt_opt;
01530 BOOL perform_loop_exit_opt;
01531 CODEREP *const NO_TRIP_COUNT = NULL;
01532
01533 BOOL need_guard = ((loop->Flags() & LOOP_PRE_REPEAT) == LOOP_PRE_REPEAT ||
01534 (loop->Flags() & LOOP_REPEAT) == LOOP_REPEAT);
01535
01536 if (iv_expr != based_iv) {
01537
01538
01539
01540
01541
01542
01543 perform_slt_opt = (new_step == 1 || new_step == -1);
01544 perform_loop_exit_opt = FALSE;
01545
01546
01547
01548
01549 init = Replace_IV_with_invar(iv_expr, based_iv, init);
01550 Is_True(new_step != 0, ("Compute_trip_count: step is 0."));
01551
01552 OPCODE mulop = OPCODE_make_op(OPR_MPY, step->Dtyp(), MTYPE_V);
01553 step = Htable()->Add_bin_node_and_fold(mulop, step,
01554 Htable()->Add_const(step->Dtyp(),
01555 new_step));
01556
01557 if (_trace) {
01558 fprintf(TFile, "Perform trip count computation for composite IV.\n");
01559 fprintf(TFile, "Composite iv_expr: \n");
01560 iv_expr->Print(0,TFile);
01561 fprintf(TFile, "Composite based_iv: \n");
01562 based_iv->Print(0,TFile);
01563 fprintf(TFile, "Composite init: \n");
01564 init->Print(0,TFile);
01565 fprintf(TFile, "Composite step: \n");
01566 step->Print(0,TFile);
01567 fprintf(TFile, "Composite bound: \n");
01568 bound->Print(0,TFile);
01569 }
01570
01571 } else {
01572 perform_loop_exit_opt = TRUE;
01573 perform_slt_opt = TRUE;
01574 }
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595 INT32 adjustment;
01596 INT32 slt_adjustment;
01597 BOOL allow_remainder;
01598 enum {UP, DOWN, DONT_CARE} direction;
01599 #ifndef TARG_X8664
01600 BOOL need_slt_opt = TRUE;
01601 #else
01602 BOOL need_slt_opt = FALSE;
01603 #endif
01604 BOOL need_inv_slt_opt = FALSE;
01605 BOOL apply_cxx_pointer_rule = FALSE;
01606 if (test_at_entry) {
01607
01608
01609
01610
01611 switch (OPCODE_operator(cmp_opc)) {
01612 case OPR_GE:
01613 direction = UP;
01614 allow_remainder = TRUE;
01615 adjustment = -1;
01616 break;
01617 case OPR_LE:
01618 direction = DOWN;
01619 allow_remainder = TRUE;
01620 adjustment = 1;
01621 break;
01622 case OPR_LT:
01623 direction = DOWN;
01624 allow_remainder = TRUE;
01625 adjustment = 0;
01626 break;
01627 case OPR_GT:
01628 direction = UP;
01629 allow_remainder = TRUE;
01630 adjustment = 0;
01631 break;
01632 case OPR_EQ:
01633 direction = DONT_CARE;
01634 allow_remainder = FALSE;
01635 adjustment = 0;
01636 need_slt_opt = FALSE;
01637 apply_cxx_pointer_rule = TRUE;
01638
01639
01640
01641
01642
01643
01644 need_inv_slt_opt = !loop->Exit_early();
01645 break;
01646 case OPR_NE:
01647 default:
01648 return NO_TRIP_COUNT;
01649 }
01650 } else {
01651
01652
01653 switch (OPCODE_operator(cmp_opc)) {
01654 case OPR_GE:
01655 direction = DOWN;
01656 allow_remainder = TRUE;
01657 adjustment = 0;
01658 slt_adjustment = -1;
01659 break;
01660 case OPR_LE:
01661 direction = UP;
01662 allow_remainder = TRUE;
01663 adjustment = 0;
01664 slt_adjustment = 1;
01665 break;
01666 case OPR_LT:
01667 direction = UP;
01668 allow_remainder = TRUE;
01669 adjustment = -1;
01670 slt_adjustment = 0;
01671 break;
01672 case OPR_GT:
01673 direction = DOWN;
01674 allow_remainder = TRUE;
01675 adjustment = 1;
01676 slt_adjustment = 0;
01677 break;
01678 case OPR_NE:
01679 direction = DONT_CARE;
01680 allow_remainder = FALSE;
01681 adjustment = 0;
01682 need_slt_opt = FALSE;
01683 apply_cxx_pointer_rule = TRUE;
01684 break;
01685 case OPR_EQ:
01686 #ifdef KEY // bug 10986: special case where trip count is 1
01687 if (init == bound &&
01688 step->Kind() == CK_CONST && step->Const_val() != 0)
01689 return Htable()->Add_const(MTYPE_I4, 1);
01690
01691 #endif
01692 default:
01693 return NO_TRIP_COUNT;
01694 }
01695 }
01696
01697
01698
01699
01700
01701
01702 BOOL diff_divisable_by_step =
01703 bound->Divisable(step, Opt_stab()) && init->Divisable(step, Opt_stab());
01704 if (apply_cxx_pointer_rule &&
01705 PU_src_lang(Get_Current_PU()) == PU_CXX_LANG &&
01706 !loop->Exit_early() &&
01707 !diff_divisable_by_step &&
01708 step->Kind() == CK_CONST &&
01709 var->Divisable(step, Opt_stab())) {
01710 diff_divisable_by_step = TRUE;
01711 }
01712 if (!diff_divisable_by_step &&
01713 step->Kind() == CK_CONST &&
01714 bound->Kind() == CK_CONST &&
01715 init->Kind() == CK_CONST &&
01716 step->Const_val() != 0) {
01717 INT64 diff = bound->Const_val() - init->Const_val();
01718 diff_divisable_by_step = ((diff % step->Const_val()) == 0);
01719 }
01720
01721
01722
01723 BOOL valid_entry_test = loop->Test_at_entry() || loop->Has_entry_guard();
01724
01725
01726 if (!valid_entry_test) {
01727
01728 CODEREP *entry_test =
01729 Htable()->Add_bin_node_and_fold(cmp_opc, init, bound, cmp_stmt->Bb());
01730
01731 if (entry_test->Kind() == CK_CONST) {
01732 if (entry_test->Const_val() != 0)
01733 valid_entry_test = TRUE;
01734 } else {
01735
01736 if (Loop()->Preheader()->Pred()->Len() == 1) {
01737 BB_NODE *bb = Loop()->Preheader()->Pred()->Node();
01738 STMTREP *br = bb->Branch_stmtrep();
01739 if (bb->Next() == Loop()->Preheader() &&
01740
01741 br != NULL &&
01742 br->Op() == OPC_FALSEBR) {
01743 CODEREP *rhs = br->Rhs();
01744 if (rhs->Kind() == CK_OP) {
01745 switch (rhs->Kid_count()) {
01746 case 1:
01747 rhs = Htable()->Add_unary_node(rhs->Op(), rhs->Opnd(0));
01748 break;
01749 case 2:
01750 rhs = Htable()->Add_bin_node_and_fold(rhs->Op(),
01751 rhs->Opnd(0),
01752 rhs->Opnd(1));
01753 break;
01754 default:
01755 break;
01756 }
01757 }
01758 if (rhs == entry_test)
01759 valid_entry_test = TRUE;
01760 }
01761 }
01762 }
01763 }
01764
01765
01766 if (!valid_entry_test &&
01767 init->Kind() == CK_VAR &&
01768 !init->Is_flag_set((CR_FLAG)(CF_DEF_BY_PHI|CF_DEF_BY_CHI)) &&
01769 init->Defstmt() != NULL) {
01770
01771 CODEREP *entry_test =
01772 Htable()->Add_bin_node_and_fold(cmp_opc, init->Defstmt()->Rhs(),
01773 bound, cmp_stmt->Bb());
01774 if (entry_test->Kind() == CK_CONST) {
01775 if (entry_test->Const_val() != 0)
01776 valid_entry_test = TRUE;
01777 } else {
01778
01779 if (Loop()->Preheader()->Pred()->Len() == 1) {
01780 BB_NODE *bb = Loop()->Preheader()->Pred()->Node();
01781 STMTREP *br = bb->Branch_stmtrep();
01782 if (bb->Next() == Loop()->Preheader() &&
01783
01784 br != NULL &&
01785 br->Op() == OPC_FALSEBR) {
01786 CODEREP *rhs = br->Rhs();
01787 if (rhs->Kind() == CK_OP)
01788 switch (rhs->Kid_count()) {
01789 case 1:
01790 rhs = Htable()->Add_unary_node(rhs->Op(), rhs->Opnd(0));
01791 break;
01792 case 2:
01793 rhs = Htable()->Add_bin_node_and_fold(rhs->Op(),
01794 rhs->Opnd(0),
01795 rhs->Opnd(1));
01796 break;
01797 default:
01798 break;
01799 }
01800 if (rhs == entry_test)
01801 valid_entry_test = TRUE;
01802 }
01803 }
01804 }
01805 }
01806
01807
01808
01809
01810 if (!valid_entry_test) {
01811 perform_slt_opt = FALSE;
01812 need_guard = TRUE;
01813 }
01814
01815
01816
01817
01818
01819
01820 CODEREP *trip_count = NO_TRIP_COUNT;
01821 #if defined(TARG_SL)
01822 if (!diff_divisable_by_step) {
01823 if (step->Kind() == CK_CONST && step->Const_val() < 0) {
01824 return NO_TRIP_COUNT;
01825 }
01826 }
01827 #endif
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840 MTYPE tripcount_type;
01841 if (primary_cand == NULL)
01842 tripcount_type = (MTYPE_size_min(based_iv->Dtyp()) ==
01843 MTYPE_size_min(MTYPE_I4)) ? MTYPE_I4 : MTYPE_I8;
01844 else
01845 tripcount_type = (MTYPE_size_min(primary_cand->Dtype()) ==
01846 MTYPE_size_min(MTYPE_I4)) ? MTYPE_I4 : MTYPE_I8;
01847
01848 if (allow_remainder) {
01849 if (bound->Kind() == CK_CONST &&
01850 init->Kind() == CK_CONST &&
01851 step->Kind() == CK_CONST) {
01852 if (step->Const_val() != 0) {
01853 INT64 diff =
01854 bound->Const_val() - init->Const_val() + step->Const_val() +
01855 adjustment;
01856 trip_count =
01857 Htable()->Add_const(tripcount_type, (diff / step->Const_val()));
01858 }
01859 } else if ((step->Kind() == CK_CONST && step->Const_val() != 0) ||
01860 WOPT_Enable_Generate_Trip_Count == 2 ||
01861 (WOPT_Enable_Generate_Trip_Count == 1 &&
01862 IS_FORTRAN &&
01863 (loop->Flags() & LOOP_DO) != 0)) {
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874 MTYPE dtype = OPCODE_desc(cmp_opc);
01875 OPCODE addop = OPCODE_make_op(OPR_ADD, dtype, MTYPE_V);
01876 OPCODE subop = OPCODE_make_op(OPR_SUB, dtype, MTYPE_V);
01877 CODEREP *one = Htable()->Add_const(dtype, 1);
01878
01879 if (step->Kind() == CK_CONST && step->Const_val() < 0) {
01880
01881
01882 CODEREP *neg_step = Htable()->Add_const(dtype, - step->Const_val());
01883
01884 CODEREP *tmp_cr = Htable()->Add_bin_node_and_fold(subop, init,
01885 bound);
01886 tmp_cr = Htable()->Add_bin_node_and_fold(addop, tmp_cr, neg_step);
01887 if (adjustment == 1)
01888 tmp_cr = Htable()->Add_bin_node_and_fold(subop, tmp_cr, one);
01889 else if (adjustment == -1)
01890 tmp_cr = Htable()->Add_bin_node_and_fold(addop, tmp_cr, one);
01891
01892 OPCODE divop = OPCODE_make_op(OPR_DIV, tripcount_type, MTYPE_V);
01893 trip_count =
01894 Htable()->Add_bin_node_and_fold(divop,
01895 tmp_cr->Fixup_type(tripcount_type,
01896 Htable()),
01897 neg_step->Fixup_type(tripcount_type,
01898 Htable()));
01899
01900 } else {
01901
01902
01903
01904 CODEREP *tmp_cr =
01905 Htable()->Add_bin_node_and_fold(subop, bound, init);
01906 tmp_cr = Htable()->Add_bin_node_and_fold(addop, tmp_cr, step);
01907 if (adjustment == 1)
01908 tmp_cr = Htable()->Add_bin_node_and_fold(addop, tmp_cr, one);
01909 else if (adjustment == -1)
01910 tmp_cr = Htable()->Add_bin_node_and_fold(subop, tmp_cr, one);
01911
01912 #ifdef TARG_SL
01913
01914 tripcount_type = (tmp_cr->Dtyp() == MTYPE_U4) ? MTYPE_U4 : tripcount_type;
01915 #endif
01916 OPCODE divop = OPCODE_make_op(OPR_DIV, tripcount_type, MTYPE_V);
01917 trip_count =
01918 Htable()->Add_bin_node_and_fold(divop,
01919 tmp_cr->Fixup_type(tripcount_type,
01920 Htable()),
01921 step->Fixup_type(tripcount_type,
01922 Htable()));
01923 }
01924 }
01925 } else {
01926 Is_True(adjustment == 0,
01927 ("IVR: when allow_remainder is FALSE, adjustment must be 0."));
01928
01929
01930
01931
01932
01933 if (diff_divisable_by_step) {
01934 MTYPE dtype = OPCODE_desc(cmp_opc);
01935
01936 if (step->Kind() == CK_CONST && step->Const_val() < 0) {
01937
01938 OPCODE subop = OPCODE_make_op(OPR_SUB, dtype, MTYPE_V);
01939 CODEREP *diff = Htable()->Add_bin_node_and_fold(subop, init, bound);
01940 #ifdef KEY // bug 3738
01941 if (MTYPE_byte_size(var->Dsctyp()) < 4) {
01942 diff = Htable()->Add_unary_node(
01943 OPCODE_make_op(OPR_CVTL, dtype, MTYPE_V), diff);
01944 diff->Set_offset(MTYPE_size_min(var->Dsctyp()));
01945 }
01946 #endif
01947 CODEREP *neg_step = Htable()->Add_const(tripcount_type, -
01948 step->Const_val());
01949
01950 OPCODE divop = OPCODE_make_op(OPR_DIV, tripcount_type, MTYPE_V);
01951 trip_count =
01952 Htable()->Add_bin_node_and_fold(divop,
01953 diff->Fixup_type(tripcount_type,
01954 Htable()),
01955 neg_step);
01956 } else {
01957
01958 OPCODE subop = OPCODE_make_op(OPR_SUB, dtype, MTYPE_V);
01959 CODEREP *diff = Htable()->Add_bin_node_and_fold(subop, bound, init);
01960
01961 OPCODE divop = OPCODE_make_op(OPR_DIV, tripcount_type, MTYPE_V);
01962 trip_count =
01963 Htable()->Add_bin_node_and_fold(divop,
01964 diff->Fixup_type(tripcount_type,
01965 Htable()),
01966 step->Fixup_type(tripcount_type,
01967 Htable()));
01968 }
01969 }
01970 }
01971
01972 if (trip_count) {
01973 CODEREP *tmp = Htable()->Canon_rhs(trip_count);
01974 if (tmp) trip_count = tmp;
01975 }
01976
01977 if (_trace) {
01978 fprintf(TFile,
01979 "IVR direction is %s; allow remainder is %s;"
01980 "adjustment = %d;\n"
01981 "IVR slt_adjustment = %d; divisable by step = %s;"
01982 "need_guard = %s; valid_entry_test = %s.\n",
01983 direction == UP ? "UP" : "DOWN",
01984 allow_remainder ? "T" : "F",
01985 adjustment,
01986 slt_adjustment,
01987 diff_divisable_by_step ? "T" : "F",
01988 need_guard ? "T" : "F",
01989 valid_entry_test ? "T" : "F");
01990 fprintf(TFile, "Bound: \n");
01991 bound->Print(0, TFile);
01992 fprintf(TFile, "Init: \n");
01993 init->Print(0, TFile);
01994 if (trip_count) {
01995 fprintf(TFile, "Trip count: \n");
01996 trip_count->Print(0, TFile);
01997 }
01998 else
01999 fprintf(TFile, "Trip count: NULL\n");
02000 }
02001
02002
02003 if (step->Kind() == CK_CONST) {
02004 switch (direction) {
02005 case UP:
02006 if (step->Const_val() < 0) return NO_TRIP_COUNT;
02007 break;
02008 case DOWN:
02009 if (step->Const_val() > 0) return NO_TRIP_COUNT;
02010 break;
02011 case DONT_CARE:
02012 break;
02013 }
02014 }
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031 if (need_guard) {
02032 if (trip_count &&
02033 trip_count->Kind() == CK_CONST &&
02034 trip_count->Const_val() == 0)
02035 return NO_TRIP_COUNT;
02036 if (init == bound)
02037
02038 return NO_TRIP_COUNT;
02039 }
02040
02041
02042
02043
02044
02045
02046 if (Phase() == MAINOPT_PHASE && !test_at_entry && need_slt_opt &&
02047 perform_slt_opt) {
02048
02049 Is_True(cmp_stmt->Opr() == OPR_TRUEBR,
02050 ("slt optimization only understands TRUEBR."));
02051
02052 OPCODE slt_cmp_opc = OPCODE_make_op(OPR_NE, OPCODE_rtype(cmp_opc),
02053 OPCODE_desc(cmp_opc));
02054 CODEREP *new_cond = NULL;
02055 MTYPE dtype = OPCODE_desc(cmp_opc);
02056
02057 if (diff_divisable_by_step) {
02058 CODEREP *trip_var;
02059 CODEREP *trip_bound;
02060 CODEREP *cond = cmp_stmt->Rhs();
02061
02062
02063 if (!swapped) {
02064 trip_var = cond->Opnd(0);
02065 trip_bound = cond->Opnd(1);
02066 } else {
02067 trip_var = cond->Opnd(1);
02068 trip_bound = cond->Opnd(0);
02069 }
02070
02071 if (iv_expr == based_iv)
02072 Is_True(trip_var->Kind() == CK_VAR, ("trip var is not CK_VAR."));
02073
02074 OPCODE addop = OPCODE_make_op(OPR_ADD, dtype, MTYPE_V);
02075 if (slt_adjustment == 1)
02076 trip_bound = Htable()->Add_bin_node_and_fold(addop,
02077 trip_bound,
02078 step);
02079 else if (slt_adjustment == -1)
02080 trip_bound = Htable()->Add_bin_node_and_fold(addop,
02081 trip_bound,
02082 step);
02083 new_cond = Htable()->Add_bin_node_and_fold(slt_cmp_opc,
02084 trip_var,
02085 trip_bound,
02086 cmp_stmt->Bb());
02087 }
02088
02089
02090
02091 else if (step->Kind() == CK_CONST) {
02092 Warn_todo("SLT: adjust the upper bound to make"
02093 " (bound - init) divisable by the step.");
02094 }
02095
02096
02097 if (new_cond) {
02098 cmp_stmt->Set_rhs(new_cond);
02099 Inc_slt_counter();
02100 }
02101 }
02102
02103
02104
02105
02106
02107 if ((Phase() == PREOPT_PHASE ||
02108 Phase() == PREOPT_LNO_PHASE ||
02109 Phase() == PREOPT_IPA0_PHASE ||
02110 Phase() == PREOPT_IPA1_PHASE) &&
02111 test_at_entry && need_inv_slt_opt && perform_slt_opt &&
02112 diff_divisable_by_step && step->Kind() == CK_CONST &&
02113 cmp_stmt->Opr() == OPR_FALSEBR) {
02114
02115 CODEREP *trip_var;
02116 CODEREP *trip_bound;
02117 CODEREP *cond = cmp_stmt->Rhs();
02118
02119
02120 if (!swapped) {
02121 trip_var = cond->Opnd(0);
02122 trip_bound = cond->Opnd(1);
02123 } else {
02124 trip_var = cond->Opnd(1);
02125 trip_bound = cond->Opnd(0);
02126 }
02127
02128
02129 TY_IDX ty = trip_var->Kind() == CK_VAR ? trip_var->Lod_ty() : 0;
02130 if (WOPT_Enable_Aggressive_Doloop_Promotion ||
02131 MTYPE_is_signed(OPCODE_desc(cmp_opc)) ||
02132 (ty != 0 && TY_kind(ty) == KIND_POINTER)) {
02133
02134 OPCODE inv_slt_cmp_opc =
02135 OPCODE_make_op(step->Const_val() > 0 ? OPR_LT : OPR_GT,
02136 OPCODE_rtype(cmp_opc), OPCODE_desc(cmp_opc));
02137 CODEREP *new_cond =
02138 Htable()->Add_bin_node_and_fold(inv_slt_cmp_opc, trip_var,
02139 trip_bound,
02140 cmp_stmt->Bb());
02141
02142
02143 if (new_cond) {
02144 cmp_stmt->Set_rhs(new_cond);
02145 }
02146 }
02147 }
02148
02149 if (trip_count == NO_TRIP_COUNT) return NO_TRIP_COUNT;
02150
02151
02152
02153
02154 if (need_guard) {
02155 OPCODE min_op = OPCODE_make_op(OPR_MAX, trip_count->Dtyp(), MTYPE_V);
02156 CODEREP *one = Htable()->Add_const(trip_count->Dtyp(), 1);
02157 trip_count = Htable()->Add_bin_node_and_fold(min_op, trip_count, one);
02158 }
02159
02160
02161
02162
02163
02164 if (Phase() == MAINOPT_PHASE) {
02165
02166
02167
02168 if (trip_count->Kind() != CK_CONST) {
02169 STMTREP *loop_info_stmt = CXX_NEW(STMTREP(OPC_EVAL),
02170 Htable()->Mem_pool());
02171 loop_info_stmt->Set_rhs(trip_count);
02172 loop->Preheader()->Append_stmtrep(loop_info_stmt);
02173 loop->Set_trip_count_stmt(loop_info_stmt);
02174 } else
02175 loop->Set_trip_count_expr(trip_count);
02176 Inc_trip_counter();
02177 }
02178
02179
02180
02181
02182
02183
02184
02185 if (!perform_loop_exit_opt) return NO_TRIP_COUNT;
02186
02187
02188 if (step->Kind() != CK_CONST) return NO_TRIP_COUNT;
02189
02190 if (trip_count->Kind() == CK_CONST) {
02191
02192
02193 if (trip_count->Const_val() < 0) return NO_TRIP_COUNT;
02194 }
02195 return trip_count;
02196 }
02197
02198
02199
02200 void
02201 IVR::Determine_trip_IV_and_exit_count(BB_LOOP *loopinfo,
02202 IV_CAND **trip_iv_found,
02203 IV_CAND *primary)
02204 {
02205
02206
02207
02208 STMTREP *stmt = loopinfo->End()->Last_stmtrep();
02209
02210 Is_True(stmt->Opr() == OPR_TRUEBR || stmt->Opr() == OPR_FALSEBR,
02211 ("Don't know how to handle loop end block without"
02212 " OPR_TRUEBR/FALSEBR"));
02213
02214
02215 CODEREP *cond = stmt->Rhs();
02216
02217
02218
02219 if (cond->Kind() == CK_OP && OPCODE_is_compare(cond->Op())) {
02220 CODEREP *tmp_cond = Htable()->Add_bin_node_and_fold(cond->Op(),
02221 cond->Opnd(0),
02222 cond->Opnd(1),
02223 stmt->Bb());
02224 if (cond != tmp_cond) {
02225 cond = tmp_cond;
02226 stmt->Set_rhs(cond);
02227 }
02228 }
02229
02230 if (cond->Kind() != CK_OP) return;
02231 if (cond->Kid_count() != 2) return;
02232
02233 IV_CAND *trip_cand;
02234 BOOL found = FALSE;
02235 CODEREP *trip_bound;
02236 CODEREP *trip_iv_expr;
02237 OPCODE cmp_op = cond->Op();
02238 BOOL swapped = FALSE;
02239
02240
02241
02242 if (stmt->Opr() == OPR_FALSEBR) {
02243 switch (OPCODE_operator(cmp_op)) {
02244 case OPR_LT:
02245 cmp_op=OPCODE_make_op(OPR_GE,OPCODE_rtype(cmp_op),OPCODE_desc(cmp_op));
02246 break;
02247 case OPR_LE:
02248 cmp_op=OPCODE_make_op(OPR_GT,OPCODE_rtype(cmp_op),OPCODE_desc(cmp_op));
02249 break;
02250 case OPR_GT:
02251 cmp_op=OPCODE_make_op(OPR_LE,OPCODE_rtype(cmp_op),OPCODE_desc(cmp_op));
02252 break;
02253 case OPR_GE:
02254 cmp_op=OPCODE_make_op(OPR_LT,OPCODE_rtype(cmp_op),OPCODE_desc(cmp_op));
02255 break;
02256 case OPR_NE:
02257 cmp_op=OPCODE_make_op(OPR_EQ,OPCODE_rtype(cmp_op),OPCODE_desc(cmp_op));
02258 break;
02259 case OPR_EQ:
02260 cmp_op=OPCODE_make_op(OPR_NE,OPCODE_rtype(cmp_op),OPCODE_desc(cmp_op));
02261 break;
02262 default:
02263 return;
02264 }
02265 }
02266
02267
02268
02269
02270
02271
02272 if (WOPT_Enable_Aggr_Invariant) {
02273 if (!loopinfo->Invariant_cr(cond->Opnd(0)) &&
02274 !loopinfo->Invariant_cr(cond->Opnd(1))) {
02275 Htable()->Convert_iload_to_loop_invariant(loopinfo, cond);
02276 }
02277 }
02278
02279
02280
02281
02282
02283 if (loopinfo->Invariant_cr(cond->Opnd(0))) {
02284 swapped = TRUE;
02285 trip_bound = cond->Opnd(0);
02286 trip_iv_expr = cond->Opnd(1);
02287
02288 switch (OPCODE_operator(cmp_op)) {
02289 case OPR_LT:
02290 cmp_op=OPCODE_make_op(OPR_GT,OPCODE_rtype(cmp_op),OPCODE_desc(cmp_op));
02291 break;
02292 case OPR_LE:
02293 cmp_op=OPCODE_make_op(OPR_GE,OPCODE_rtype(cmp_op),OPCODE_desc(cmp_op));
02294 break;
02295 case OPR_GT:
02296 cmp_op=OPCODE_make_op(OPR_LT,OPCODE_rtype(cmp_op),OPCODE_desc(cmp_op));
02297 break;
02298 case OPR_GE:
02299 cmp_op=OPCODE_make_op(OPR_LE,OPCODE_rtype(cmp_op),OPCODE_desc(cmp_op));
02300 break;
02301 }
02302 } else {
02303 swapped = FALSE;
02304 trip_bound = cond->Opnd(1);
02305 trip_iv_expr = cond->Opnd(0);
02306 }
02307
02308
02309
02310 IV_EXPR ivx;
02311 ivx.Init(trip_iv_expr, loopinfo);
02312
02313
02314 CODEREP *based_iv = NULL;
02315 INT64 new_step = 0;
02316 if (ivx.Valid_expr()) {
02317 based_iv = ivx.Based_iv();
02318 new_step = ivx.Step();
02319 IDTYPE trip_aux_id = based_iv->Aux_id();
02320 vector<IV_CAND*>::iterator iv_cand_iter;
02321 for (iv_cand_iter = iv_cand_container.begin();
02322 iv_cand_iter != iv_cand_container.end();
02323 iv_cand_iter++) {
02324 trip_cand = *iv_cand_iter;
02325 if (trip_aux_id == trip_cand->Var()->Aux_id() &&
02326 (Opt_stab()->Aux_stab_entry(trip_aux_id)->Mclass() &
02327 MTYPE_CLASS_UNSIGNED_INTEGER)) {
02328 found = TRUE;
02329 break;
02330 }
02331 }
02332 }
02333
02334 if (_trace) {
02335 if (found)
02336 fprintf(TFile, "Trip IV is %d.\n", trip_cand->Var()->Aux_id());
02337 else
02338 fprintf(TFile, "Trip IV is not found.\n");
02339 }
02340
02341
02342 if (!found) return;
02343 *trip_iv_found = trip_cand;
02344
02345 loopinfo->Set_iv(trip_cand->Var());
02346
02347
02348 CODEREP *trip_init =
02349 Htable()->Convert_to_loop_invar(trip_cand->Init_value(), loopinfo);
02350
02351 if (!loopinfo->Invariant_cr(trip_cand->Step_value())) return;
02352 if (!loopinfo->Invariant_cr(trip_bound)) return;
02353
02354
02355
02356
02357
02358 CODEREP *trip_step =
02359 Htable()->Convert_to_loop_invar(trip_cand->Step_value(), loopinfo);
02360 trip_bound = Htable()->Convert_to_loop_invar(trip_bound, loopinfo);
02361
02362 if (trip_init == NULL || trip_step == NULL || trip_bound == NULL)
02363 return;
02364
02365 #ifdef KEY // bug 13728: if there is wraparound, do not continue
02366 if (trip_init->Kind() == CK_CONST && trip_step->Kind() == CK_CONST &&
02367 trip_bound->Kind() == CK_CONST) {
02368 if (MTYPE_signed(trip_cand->Var()->Dtyp()))
02369 if (trip_step->Const_val() > 0) {
02370 if (trip_init->Const_val() > trip_bound->Const_val())
02371 return;
02372 }
02373 else {
02374 if (trip_init->Const_val() < trip_bound->Const_val())
02375 return;
02376 }
02377 else
02378 if (trip_step->Const_val() > 0) {
02379 if ((UINT64)trip_init->Const_val() > (UINT64)trip_bound->Const_val())
02380 return;
02381 }
02382 else {
02383 if ((UINT64)trip_init->Const_val() < (UINT64)trip_bound->Const_val())
02384 return;
02385 }
02386 }
02387 #endif
02388
02389 if (loopinfo->Test_at_entry()) {
02390
02391
02392
02393
02394 CODEREP *trip_init_adjusted = trip_init;
02395 if (trip_iv_expr != based_iv)
02396 trip_init_adjusted = Replace_IV_with_invar(trip_iv_expr, based_iv,
02397 trip_init);
02398
02399 CODEREP *cmp = swapped ?
02400 Htable()->Add_bin_node_and_fold(cond->Op(), trip_bound,
02401 trip_init_adjusted) :
02402 Htable()->Add_bin_node_and_fold(cond->Op(), trip_init_adjusted,
02403 trip_bound);
02404
02405 if (cmp->Kind() == CK_CONST) {
02406
02407 if ((stmt->Opr()==OPR_TRUEBR && cmp->Const_val()!=0)||
02408 (stmt->Opr()==OPR_FALSEBR && cmp->Const_val()==0))
02409 Set_trip_count(Htable()->Add_const(MTYPE_I4, 0));
02410 else
02411 Set_trip_count(Compute_trip_count(cmp_op, loopinfo, trip_bound,
02412 trip_cand->Var(), trip_init,
02413 trip_step,
02414 trip_iv_expr, based_iv, new_step,
02415 TRUE, stmt, swapped, primary));
02416 } else {
02417
02418
02419
02420 Set_trip_count(NULL);
02421
02422 CODEREP *trip_count = Compute_trip_count(cmp_op, loopinfo, trip_bound,
02423 trip_cand->Var(), trip_init,
02424 trip_step, trip_iv_expr,
02425 based_iv, new_step,
02426 TRUE, stmt, swapped, primary);
02427 if (trip_count != NULL &&
02428 loopinfo->Invariant_cr(cmp) &&
02429 stmt->Opr() == OPR_FALSEBR) {
02430
02431 OPCODE select_op = OPCODE_make_op(OPR_SELECT,
02432 trip_count->Dtyp(), MTYPE_V);
02433 CODEREP *zero = Htable()->Add_const(MTYPE_I4, 0);
02434 CODEREP *select = Htable()->Add_tertiary_node(select_op, cmp,
02435 trip_count, zero);
02436
02437 Set_entry_test(cmp);
02438
02439
02440
02441
02442
02443
02444
02445 switch (cmp->Opr()) {
02446 case OPR_GT:
02447 case OPR_GE:
02448 if (cmp->Opnd(0) == select->Opnd(1) &&
02449 cmp->Opnd(1) == select->Opnd(2)) {
02450 select = Htable()->Add_bin_node_and_fold(
02451 OPCODE_make_op(OPR_MAX, trip_count->Dtyp(), MTYPE_V),
02452 select->Opnd(1), select->Opnd(2));
02453 }
02454 break;
02455 case OPR_LT:
02456 case OPR_LE:
02457 if (cmp->Opnd(0) == select->Opnd(2) &&
02458 cmp->Opnd(1) == select->Opnd(1)) {
02459 select = Htable()->Add_bin_node_and_fold(
02460 OPCODE_make_op(OPR_MAX, trip_count->Dtyp(), MTYPE_V),
02461 select->Opnd(1), select->Opnd(2));
02462 }
02463 break;
02464 }
02465 Set_guarded_trip_count(select);
02466
02467 if (_trace) {
02468 fprintf(TFile, "IVR: no regular trip count generated.\n");
02469 fprintf(TFile, "IVR: generated guarded trip count: \n");
02470 Guarded_trip_count()->Print(0, TFile);
02471 fprintf(TFile, "IVR: entry test of the loop is: \n");
02472 Entry_test()->Print(0, TFile);
02473 }
02474 } else
02475 Set_guarded_trip_count(NULL);
02476 }
02477
02478 } else if (loopinfo->Test_at_exit()) {
02479
02480 Is_True(stmt->Opr() == OPR_TRUEBR,
02481 ("slt opt only works with TRUEBR."));
02482
02483 Set_trip_count(Compute_trip_count(cmp_op, loopinfo, trip_bound,
02484 trip_cand->Var(), trip_init,
02485 trip_step,
02486 trip_iv_expr, based_iv, new_step,
02487 FALSE, stmt, swapped, primary));
02488
02489 #ifdef Is_True_On
02490
02491 if (Phase() == MAINOPT_PHASE &&
02492 (loopinfo->Flags() & LOOP_DO) == LOOP_DO) {
02493 if (loopinfo->Trip_count_stmt() == NULL &&
02494 loopinfo->Trip_count_expr() == NULL)
02495 DevWarn("Trip count is not generated for a DO-loop.");
02496 }
02497 #endif
02498 }
02499 }
02500
02501
02502
02503
02504 void
02505 IVR::Replace_secondary_IV(const IV_CAND *primary,
02506 const IV_CAND *secondary,
02507 BB_NODE *startbb,
02508 BB_LOOP *loop)
02509 {
02510
02511
02512
02513 Is_True(primary->Step_value()->Kind() == CK_CONST &&
02514 primary->Step_value()->Const_val() == 1,
02515 ("primary IV is not stride 1."));
02516
02517
02518
02519 OPCODE subop = OPCODE_make_op(OPR_SUB, primary->Dtype(), MTYPE_V);
02520 CODEREP *iter_count =
02521 Htable()->Add_bin_node_and_fold(subop, primary->Var(),
02522 primary->Init_value());
02523
02524
02525 MTYPE dtype = secondary->Dtype();
02526 iter_count = iter_count->Fixup_type(dtype, Htable());
02527
02528
02529
02530
02531
02532
02533
02534
02535 CODEREP *second_iv;
02536 if (secondary->Step_value()->Kind() == CK_CONST &&
02537 secondary->Step_value()->Const_val() < 0) {
02538 OPCODE mulop = OPCODE_make_op(OPR_MPY, dtype, MTYPE_V);
02539 CODEREP *new_step =
02540 Htable()->Add_const(dtype, - secondary->Step_value()->Const_val());
02541 CODEREP *iter_inc =
02542 Htable()->Add_bin_node_and_fold(mulop, iter_count, new_step);
02543 OPCODE subop = OPCODE_make_op(OPR_SUB, dtype, MTYPE_V);
02544 second_iv =
02545 Htable()->Add_bin_node_and_fold(subop, secondary->Init_value(),
02546 iter_inc);
02547
02548 } else {
02549 OPCODE mulop = OPCODE_make_op(OPR_MPY, dtype, MTYPE_V);
02550 CODEREP *iter_inc =
02551 Htable()->Add_bin_node_and_fold(mulop, iter_count,
02552 secondary->Step_value());
02553 OPCODE addop = OPCODE_make_op(OPR_ADD, dtype, MTYPE_V);
02554 second_iv =
02555 Htable()->Add_bin_node_and_fold(addop, iter_inc,
02556 secondary->Init_value());
02557 }
02558
02559 STMTREP *newstmt =
02560 second_iv->Create_cpstmt(secondary->Var(), Htable()->Mem_pool());
02561 newstmt->Set_ivr_introduced();
02562 secondary->Var()->Reset_flag(CF_DEF_BY_PHI);
02563 secondary->Var()->Reset_flag(CF_DONT_PROP);
02564
02565 secondary->Var()->Set_defstmt(newstmt);
02566
02567 newstmt->Set_bb(startbb);
02568 startbb->Prepend_stmtrep(newstmt);
02569
02570
02571
02572
02573 #ifdef KEY
02574 if (!loop->Exit_early())
02575 Reset_dont_prop(secondary->Incr_var(), loop);
02576 #else
02577 Reset_dont_prop(secondary->Incr_var(), loop);
02578 #endif
02579
02580
02581
02582 IDTYPE aux_id = secondary->Var()->Aux_id();
02583 CODEREP *dummy_cr = Htable()->Add_def(aux_id, 0, NULL,
02584 MTYPE_UNKNOWN, MTYPE_UNKNOWN,
02585 Opt_stab()->St_ofst(aux_id),
02586 0, 0, TRUE);
02587 dummy_cr->Set_flag(CF_MADEUP_TYPE);
02588 dummy_cr->Set_flag(CF_DEF_BY_PHI);
02589 dummy_cr->Set_defphi(secondary->Phi());
02590 secondary->Phi()->Set_result(dummy_cr);
02591 secondary->Phi()->Set_dse_dead();
02592 secondary->Phi()->Reset_live();
02593 Inc_ivr_counter();
02594 }
02595
02596
02597
02598
02599
02600
02601
02602
02603
02604
02605
02606
02607
02608
02609
02610
02611 static BOOL
02612 Is_IV_cand_in_parent_loop(BB_LOOP *loop, CODEREP *inner_loop_init, CODEREP *exit_stmt_lhs)
02613 {
02614
02615
02616
02617
02618
02619
02620 BB_LOOP *parent_loop = loop->Parent();
02621 if (parent_loop == NULL) return FALSE;
02622
02623
02624 if (parent_loop->Preheader() == NULL) {
02625 DevWarn("IVR found a BB_LOOP with undefined Dohead!");
02626 return FALSE;
02627 }
02628
02629 BB_NODE *bb = parent_loop->Header();
02630 if (bb->Pred()->Len() != 2) return FALSE;
02631
02632
02633 PHI_LIST_ITER phi_iter;
02634 PHI_NODE *phi;
02635 PHI_NODE *found_phi = NULL;
02636 FOR_ALL_ELEM (phi, phi_iter, Init(bb->Phi_list())) {
02637 if (! phi->Live()) continue;
02638 CODEREP *res = phi->RESULT();
02639
02640 if (res->Kind() != CK_VAR) continue;
02641 if (res->Aux_id() == exit_stmt_lhs->Aux_id()) {
02642 found_phi = phi;
02643 break;
02644 }
02645 }
02646 if (found_phi == NULL) return FALSE;
02647
02648 if (found_phi->RESULT() != inner_loop_init) return FALSE;
02649
02650 if (exit_stmt_lhs != found_phi->OPND(0) &&
02651 exit_stmt_lhs != found_phi->OPND(1)) return FALSE;
02652
02653 return TRUE;
02654 }
02655
02656
02657
02658
02659
02660 static BOOL
02661 CR_is_equivalent(CODEREP *cr, CODEREP *def_cr)
02662 {
02663 STMTREP *dstmt;
02664 while (TRUE) {
02665 if (cr->Is_flag_set(CF_IS_ZERO_VERSION))
02666 return FALSE;
02667 if (cr == def_cr)
02668 return TRUE;
02669 if (cr->Is_flag_set(CF_DEF_BY_PHI))
02670 return FALSE;
02671 if (cr->Is_flag_set(CF_DEF_BY_CHI)) {
02672 dstmt = cr->Defstmt();
02673 if (dstmt != NULL &&
02674 dstmt->Is_identity_assignment_removable()) {
02675 cr = cr->Defchi()->OPND();
02676 } else
02677 return FALSE;
02678 } else {
02679 if ((dstmt = cr->Defstmt()) != NULL &&
02680 dstmt->Is_identity_assignment_removable()) {
02681 cr = dstmt->Rhs();
02682 } else
02683 return FALSE;
02684 }
02685 }
02686 }
02687
02688
02689
02690
02691 void
02692 IVR::Update_exit_stmt(const IV_CAND *secondary,
02693 BB_NODE *bb_merge,
02694 BB_LOOP *loop)
02695 {
02696 if (Trip_count() == NULL &&
02697 Guarded_trip_count() == NULL)
02698 return;
02699
02700
02701 STMTREP *exit_stmt = NULL;
02702 STMTREP_ITER stmt_iter(bb_merge->Stmtlist());
02703 STMTREP *stmt;
02704
02705 CODEREP *match_val = NULL;
02706 if (loop->Test_at_entry())
02707 match_val = secondary->Var();
02708 else if (loop->Test_at_exit())
02709 match_val = secondary->Incr_var();
02710
02711 if (match_val) {
02712 FOR_ALL_NODE(stmt, stmt_iter, Init()) {
02713 if (stmt->Is_identity_assignment_removable()) {
02714 if (stmt->Rhs() == match_val ||
02715 CR_is_equivalent(stmt->Rhs(), match_val)) {
02716 exit_stmt = stmt;
02717 break;
02718 }
02719 }
02720 }
02721 }
02722 if (exit_stmt == NULL) return;
02723
02724 CODEREP *trip_count;
02725 if (Trip_count() != NULL)
02726 trip_count = Trip_count();
02727 else if (Guarded_trip_count() != NULL &&
02728 Is_IV_cand_in_parent_loop(loop, secondary->Init_var(), stmt->Lhs()))
02729 trip_count = Guarded_trip_count();
02730 else if (Trip_count_primary_IV() != NULL)
02731 trip_count = Trip_count_primary_IV();
02732 else
02733 return;
02734
02735
02736
02737
02738
02739
02740 MTYPE dtype = secondary->Dtype();
02741 trip_count = trip_count->Fixup_type(dtype, Htable());
02742
02743 OPCODE mulop = OPCODE_make_op(OPR_MPY, dtype, MTYPE_V);
02744 CODEREP *exit_value;
02745
02746 if (secondary->Step_value()->Kind() == CK_CONST &&
02747 secondary->Step_value()->Const_val() < 0) {
02748 OPCODE subop = OPCODE_make_op(OPR_SUB, dtype, MTYPE_V);
02749 CODEREP *new_step =
02750 Htable()->Add_const(dtype, - secondary->Step_value()->Const_val());
02751 CODEREP *iter_inc =
02752 Htable()->Add_bin_node_and_fold(mulop, trip_count, new_step);
02753 exit_value =
02754 Htable()->Add_bin_node_and_fold(subop, secondary->Init_value(), iter_inc);
02755 } else {
02756 OPCODE addop = OPCODE_make_op(OPR_ADD, dtype, MTYPE_V);
02757 CODEREP *iter_inc =
02758 Htable()->Add_bin_node_and_fold(mulop, trip_count,
02759 secondary->Step_value());
02760 exit_value =
02761 Htable()->Add_bin_node_and_fold(addop, secondary->Init_value(),
02762 iter_inc);
02763 }
02764
02765 exit_stmt->Set_rhs(exit_value);
02766 Inc_exit_value_counter();
02767 }
02768
02769
02770
02771
02772
02773
02774
02775
02776
02777 void
02778 IVR::Convert_all_ivs(BB_LOOP *loop)
02779 {
02780 if (!loop->Well_formed()) return;
02781 if (loop->End() == NULL) return;
02782
02783 Init_loop(loop);
02784
02785
02786 if ((loop->Flags() & LOOP_PRE_REPEAT) == LOOP_PRE_REPEAT)
02787 return;
02788
02789 Ident_all_iv_cands(loop, loop->Header());
02790
02791 vector<IV_CAND*>::iterator iv_cand_iter;
02792 for (iv_cand_iter = iv_cand_container.begin();
02793 iv_cand_iter != iv_cand_container.end();
02794 iv_cand_iter++) {
02795 IV_CAND *cur_iv = *iv_cand_iter;
02796 CODEREP *new_init = Htable()->Convert_to_loop_invar(cur_iv->Init_value(),
02797 loop);
02798 cur_iv->Set_init_value(new_init);
02799 }
02800
02801
02802 IV_CAND *primary = Choose_primary_IV(loop);
02803
02804
02805 IV_CAND *trip_iv = NULL;
02806 Determine_trip_IV_and_exit_count(loop, &trip_iv, primary);
02807 CODEREP *trip_count = Trip_count();
02808
02809
02810
02811
02812 loop->Set_entry_test( Entry_test() );
02813
02814 if (_trace) {
02815 if (trip_count != NULL) {
02816 if (trip_count->Kind() == CK_CONST)
02817 fprintf(TFile, "IVR: exit trip count is %lld\n",
02818 trip_count->Const_val());
02819 else {
02820 fprintf(TFile, "IVR: exit trip count is ");
02821 trip_count->Print(0,TFile);
02822 }
02823 } else
02824 fprintf(TFile, "IVR exit value is not determined.\n");
02825 }
02826
02827 if (primary && trip_iv && ivr_generated_primary) {
02828 AUX_ID primary_id = primary->Var()->Aux_id();
02829 ST *trip_st = Opt_stab()->St(trip_iv->Var()->Aux_id());
02830 #ifdef KEY
02831 if (ST_class(Opt_stab()->St(primary_id)) == CLASS_PREG)
02832 #endif
02833 Set_Preg_Name((PREG_NUM) Opt_stab()->St_ofst(primary_id),
02834 ST_name(trip_st));
02835 if (_trace)
02836 fprintf(TFile, "IVR: change preg %lld index name to %s.\n",
02837 Opt_stab()->St_ofst(primary_id),
02838 ST_name(trip_st));
02839 }
02840
02841
02842
02843
02844
02845 if (Phase() == MAINOPT_PHASE &&
02846 trip_count != NULL &&
02847 trip_count->Kind() == CK_CONST &&
02848 trip_count->Const_val() == 1 &&
02849 loop->Test_at_exit()) {
02850 BB_NODE *test = loop->End();
02851 if (_trace)
02852 fprintf(TFile,
02853 "IVR: loop executes one -- removing loop back edge at BB%d\n",
02854 test->Id());
02855 Is_True(test->Next() == loop->Merge(),
02856 ("IVR: loop->Merge() is not loop->Test()->Next()"));
02857 Cfg()->Remove_path(test, loop->Body());
02858 if ( Cfg()->Feedback() )
02859 Cfg()->Feedback()->Delete_edge( test->Id(), loop->Body()->Id() );
02860
02861 loop->End()->Remove_stmtrep(test->Branch_stmtrep());
02862 Cfg()->Change_block_kind(test, BB_GOTO);
02863 Set_rebuild_loops();
02864 return;
02865 }
02866
02867 if (primary) {
02868 if (trip_count == NULL) {
02869 if (Phase() == PREOPT_PHASE ||
02870 Phase() == PREOPT_LNO_PHASE ||
02871 Phase() == PREOPT_IPA0_PHASE ||
02872 Phase() == PREOPT_IPA1_PHASE) {
02873
02874 OPCODE subop = OPCODE_make_op(OPR_SUB, primary->Dtype(), MTYPE_V);
02875 Set_trip_count_primary_IV(Htable()->Add_bin_node_and_fold(subop,
02876 primary->Var(),
02877 primary->Init_value()));
02878 }
02879 } else {
02880
02881
02882 if (!loop->Exit_early()) {
02883
02884 Update_exit_stmt(primary, loop->Merge(), loop);
02885 }
02886 }
02887 }
02888
02889 if (primary == NULL) return;
02890
02891
02892 if (!WOPT_Enable_Replace_Second_IV)
02893 return;
02894
02895
02896 if (!WOPT_Enable_Replace_While_Loop_Second_IV &&
02897 loop->Exit_early())
02898 return;
02899
02900 loop->Set_iv(primary->Var());
02901 if (_trace) { fprintf(TFile, "PRIMARY "); primary->Print(TFile); }
02902
02903 for (iv_cand_iter = iv_cand_container.begin();
02904 iv_cand_iter != iv_cand_container.end();
02905 iv_cand_iter++) {
02906
02907 IV_CAND *secondary = *iv_cand_iter;
02908
02909
02910 if (secondary == primary) continue;
02911
02912 AUX_ID aux_id = secondary->Var()->Aux_id();
02913
02914
02915
02916 if (MTYPE_size_min(secondary->Dtype()) <
02917 MTYPE_size_min(primary->Dtype())) {
02918 if (_trace)
02919 fprintf(TFile, "IVR: skip secondary IV sym%d because secondary"
02920 " size < primary size.\n", secondary->Var()->Aux_id());
02921 continue;
02922 }
02923
02924 #ifdef TARG_X8664 // skip secondary IVs that are MTYPE_U4 for performance
02925
02926 if (secondary->Dtype() == MTYPE_U4) {
02927 if (_trace)
02928 fprintf(TFile, "IVR: skip secondary IV sym%d because of type MTYPE_U4\n"
02929 , secondary->Var()->Aux_id());
02930 continue;
02931 }
02932 #endif
02933
02934
02935
02936
02937
02938
02939
02940
02941
02942
02943
02944
02945
02946
02947 if ((MTYPE_size_min(secondary->Dtype())
02948 > MTYPE_size_min(primary->Dtype())) &&
02949 (trip_iv == NULL ||
02950 (MTYPE_size_min(trip_iv->Dtype())
02951 > MTYPE_size_min(primary->Dtype())))) {
02952 if (_trace)
02953 fprintf(TFile, "IVR: skip secondary IV sym%d because secondary IV"
02954 " size > primary IV size.\n"
02955 "and trip IV size > primary IV size\n",
02956 secondary->Var()->Aux_id());
02957 continue;
02958 }
02959
02960
02961
02962
02963
02964
02965 if (Opt_stab()->Aux_stab_entry(aux_id)->Dont_replace_iv()) {
02966 if (_trace)
02967 fprintf(TFile,
02968 "IVR: skip secondary IV sym%d because of Dont_replace_iv.\n",
02969 secondary->Var()->Aux_id());
02970 continue;
02971 }
02972
02973 if (secondary->Init_value() != NULL) {
02974
02975
02976
02977 Update_exit_stmt(secondary, loop->Merge(), loop);
02978 Replace_secondary_IV(primary, secondary, loop->Header(), loop);
02979 } else {
02980 if (_trace)
02981 fprintf(TFile, "IVR skip secondary IV sym%d because it cannot"
02982 " find init value.\n", secondary->Var()->Aux_id());
02983 Warn_todo("IVR: Generate copy for non-loop-invariant init value.");
02984 }
02985 }
02986 }
02987
02988
02989
02990
02991
02992
02993
02994
02995
02996
02997
02998
02999
03000
03001 inline BB_NODE*
03002 IVR::Get_my_regionstart(BB_NODE *bb) const
03003 {
03004 while (bb->Kind() != BB_REGIONSTART) bb = bb->Prev();
03005 return bb;
03006 }
03007
03008
03009 STMTREP*
03010 IVR::Find_parallel_pragma_stmt(BB_NODE *bb)
03011 {
03012 STMTREP *stmt;
03013 STMTREP_ITER stmt_iter(bb->Stmtlist());
03014 FOR_ALL_NODE(stmt, stmt_iter, Init()) {
03015 WN *pragma = stmt->Orig_wn();
03016 if (stmt->Op() == OPC_PRAGMA &&
03017 WN_Pragma_is_Parallel((WN_PRAGMA_ID)WN_pragma(pragma))) {
03018 if (WN_pragma_arg1(pragma) != 0)
03019 return NULL;
03020 else
03021 return stmt;
03022 }
03023 }
03024 return NULL;
03025 }
03026
03027
03028 STMTREP*
03029 IVR::Find_associated_parallel_pragma(BB_LOOP *loop, BB_NODE **contain_bb)
03030 {
03031 STMTREP *retval = NULL;
03032 BB_NODE *bb;
03033 while ( retval == NULL && loop && IS_MP_LOOP(loop) ) {
03034 bb = Get_my_regionstart(loop->Start());
03035 Is_True(bb != NULL,
03036 ("IVR::Find_parallel_retval: cannot find region start"));
03037
03038 retval = Find_parallel_pragma_stmt(bb);
03039 loop = loop->Parent();
03040 }
03041 if (retval == NULL)
03042 *contain_bb = NULL;
03043 else
03044 *contain_bb = bb;
03045 return retval;
03046 }
03047
03048
03049 STMTREP*
03050 IVR::Preprocess_mp_pragma_list(BB_LOOP *loop, BB_NODE **bb)
03051 {
03052 WN *index = loop->Index();
03053
03054 STMTREP *stmt = Find_associated_parallel_pragma(loop, bb);
03055 if (stmt) {
03056 WN *pragma = stmt->Orig_wn();
03057 Opt_stab()->Init_mp_attribute();
03058 do {
03059 ST *st = WN_st(pragma);
03060
03061 if (st) {
03062 AUX_ID vsym_id;
03063 if (ST_sclass(st) == SCLASS_FORMAL && !ST_is_value_parm(st))
03064 vsym_id = Opt_stab()->Find_vsym_with_base(st);
03065 else
03066 vsym_id =
03067 Opt_stab()->Find_sym_with_st_and_ofst(st,
03068 WN_pragma_arg1(pragma));
03069 switch ( WN_pragma(pragma) ) {
03070 case WN_PRAGMA_LOCAL:
03071 Opt_stab()->Reset_mp_shared(vsym_id);
03072 break;
03073 case WN_PRAGMA_SHARED:
03074
03075 break;
03076 case WN_PRAGMA_LASTLOCAL:
03077 Opt_stab()->Reset_mp_shared(vsym_id);
03078 Opt_stab()->Set_mp_lastlocal(vsym_id);
03079 break;
03080 case WN_PRAGMA_REDUCTION:
03081 Opt_stab()->Reset_mp_shared(vsym_id);
03082 Opt_stab()->Set_mp_reduction(vsym_id);
03083 case WN_PRAGMA_FIRSTPRIVATE:
03084 Opt_stab()->Reset_mp_shared(vsym_id);
03085 Opt_stab()->Set_mp_firstprivate(vsym_id);
03086 break;
03087 }
03088 }
03089 stmt = stmt->Next();
03090 if (stmt) pragma = stmt->Orig_wn();
03091 } while (stmt && (stmt->Op() == OPC_PRAGMA||stmt->Op() == OPC_XPRAGMA));
03092 }
03093 return stmt;
03094 }
03095
03096
03097 void
03098 IVR::Update_mp_pragma_list(BB_LOOP *loop, BB_NODE *bb, STMTREP *stmt)
03099 {
03100 WN *index = loop->Index();
03101
03102 if (Phase() != MAINOPT_PHASE && index != NULL && _iv_cands != NULL) {
03103 IV_CAND *primary_iv = NULL;
03104 BOOL second_iv_in_shared = FALSE;
03105 BOOL second_iv_in_lastlocal = FALSE;
03106 BOOL second_iv_in_reduction = FALSE;
03107 BOOL second_iv_in_firstprivate = FALSE;
03108
03109 vector<IV_CAND*>::iterator iv_cand_iter;
03110 for (iv_cand_iter = iv_cand_container.begin();
03111 iv_cand_iter != iv_cand_container.end();
03112 iv_cand_iter++) {
03113 IV_CAND *cur_iv = *iv_cand_iter;
03114 if (cur_iv->Is_primary()) {
03115 primary_iv = cur_iv;
03116 }
03117 else {
03118 AUX_STAB_ENTRY *sym =
03119 Opt_stab()->Aux_stab_entry(cur_iv->Var()->Aux_id());
03120 if (sym->Mp_shared())
03121 second_iv_in_shared = TRUE;
03122 if (sym->Mp_lastlocal())
03123 second_iv_in_lastlocal = TRUE;
03124 if (sym->Mp_reduction())
03125 second_iv_in_reduction = TRUE;
03126 if (sym->Mp_firstprivate())
03127 second_iv_in_firstprivate = TRUE;
03128 }
03129 }
03130
03131 if (primary_iv == NULL) {
03132 Warn_todo("IVR::Update_mp_pragma_list: cannot find primary_iv");
03133 return;
03134 }
03135
03136 AUX_ID prim_auxid = primary_iv->Var()->Aux_id();
03137 ST *prim_st = Opt_stab()->St(prim_auxid);
03138 if (ST_sclass(prim_st) == SCLASS_REG) {
03139 INT32 prim_ofst = Opt_stab()->St_ofst(prim_auxid);
03140 WN *pwn;
03141 if (second_iv_in_shared) {
03142
03143 pwn = WN_CreatePragma(WN_PRAGMA_SHARED,
03144 prim_st,
03145 prim_ofst,
03146 0);
03147 bb->Add_pragma(pwn, stmt, Htable()->Mem_pool());
03148 }
03149 if (second_iv_in_lastlocal) {
03150
03151 pwn = WN_CreatePragma(WN_PRAGMA_LASTLOCAL,
03152 prim_st,
03153 prim_ofst,
03154 0);
03155 bb->Add_pragma(pwn, stmt, Htable()->Mem_pool());
03156 }
03157 if (second_iv_in_reduction) {
03158
03159 pwn = WN_CreatePragma(WN_PRAGMA_REDUCTION,
03160 prim_st,
03161 prim_ofst,
03162 0);
03163 bb->Add_pragma(pwn, stmt, Htable()->Mem_pool());
03164 }
03165 if (second_iv_in_firstprivate) {
03166
03167 pwn = WN_CreatePragma(WN_PRAGMA_FIRSTPRIVATE,
03168 prim_st,
03169 prim_ofst,
03170 0);
03171 bb->Add_pragma(pwn, stmt, Htable()->Mem_pool());
03172 }
03173 }
03174 }
03175 }
03176
03177
03178 BOOL
03179 IVR::Is_mp_with_same_mp_pragma(BB_LOOP *child, BB_LOOP *parent)
03180 {
03181 BB_NODE *child_end_bb = child->End();
03182 BB_NODE *parent_end_bb = parent->End();
03183
03184 INT child_rid_id = child_end_bb->Rid_id();
03185 INT parent_rid_id = parent_end_bb->Rid_id();
03186
03187 if (child_rid_id == parent_rid_id)
03188 return TRUE;
03189
03190 BB_NODE *child_rgstart;
03191 BB_NODE *parent_rgstart;
03192
03193 Find_associated_parallel_pragma(child, &child_rgstart);
03194 Find_associated_parallel_pragma(parent, &parent_rgstart);
03195
03196 return (child_rgstart != NULL && child_rgstart == parent_rgstart);
03197 }
03198
03199
03200
03201
03202
03203
03204
03205
03206
03207
03208
03209
03210
03211
03212
03213 BOOL
03214 IVR::Process_one_loop(BB_LOOP *loop)
03215 {
03216 BOOL has_mp_do = FALSE;
03217 if (loop->Child()) {
03218 BB_LOOP_ITER loop_iter(loop->Child());
03219 BB_LOOP *child;
03220 FOR_ALL_NODE(child, loop_iter, Init()) {
03221 if (child->End() &&
03222 IS_MP_LOOP(child) &&
03223
03224 !Is_mp_with_same_mp_pragma(child, loop))
03225 has_mp_do = TRUE;
03226 if (Process_one_loop(child))
03227 has_mp_do = TRUE;
03228 }
03229 }
03230
03231
03232
03233
03234
03235
03236 if ( !WOPT_Enable_IVR_Outermost_Loop_Parallel_Region &&
03237 loop->End() &&
03238 Cfg()->Is_outermost_loop_in_parallel_region(loop,WN_PRAGMA_PDO_BEGIN) )
03239 {
03240 Is_Trace(Trace(),
03241 (TFile, "IVR::Process_one_loop: skip loop at BB:%d",
03242 loop->Header()->Id()) );
03243 return has_mp_do;
03244 }
03245
03246
03247 if (! has_mp_do) {
03248 BB_NODE *bb;
03249 STMTREP *stmt;
03250 Inc_loop_counter();
03251 if (IS_MP_LOOP(loop))
03252 stmt = Preprocess_mp_pragma_list(loop, &bb);
03253
03254
03255 Convert_all_ivs(loop);
03256
03257 if (IS_MP_LOOP(loop))
03258 Update_mp_pragma_list(loop, bb, stmt);
03259 }
03260 return has_mp_do;
03261 }
03262
03263
03264
03265
03266
03267
03268
03269
03270
03271
03272
03273 IVR::IVR(COMP_UNIT *cu, BOOL trace)
03274 {
03275 _iv_cands = NULL;
03276 _cu = cu;
03277 _htable = cu->Htable();
03278 _cfg = cu->Cfg();
03279 _opt_stab = cu->Opt_stab();
03280 _rebuild_loops = FALSE;
03281 _trace = trace;
03282 Init_counters();
03283 OPT_POOL_Initialize(&_mem_pool, "IV RECOG pool", FALSE, IVR_DUMP_FLAG);
03284 OPT_POOL_Push(&_mem_pool, IVR_DUMP_FLAG);
03285 }
03286
03287
03288
03289 IVR::~IVR(void)
03290 {
03291 Opt_tlog( "IVR", 0, "loops processed %d", Loop_counter() );
03292 Opt_tlog( "IVR", 0, "secondary IV replaced %d", Ivr_counter() );
03293 Opt_tlog( "IVR", 0, "slt opt %d", Slt_counter() );
03294 Opt_tlog( "IVR", 0, "exit-value %d; loopinfo tripcount generated %d",
03295 Exit_value_counter(), Trip_counter() );
03296
03297 OPT_POOL_Pop(&_mem_pool, IVR_DUMP_FLAG);
03298 OPT_POOL_Delete(&_mem_pool, IVR_DUMP_FLAG);
03299 }
03300
03301
03302
03303
03304
03305
03306
03307
03308
03309
03310
03311 void
03312 COMP_UNIT::Do_iv_recognition(void)
03313 {
03314 BOOL trace_ivr = Get_Trace(TP_GLOBOPT, IVR_DUMP_FLAG );
03315 if (trace_ivr) {
03316 fprintf(TFile, "%sDump before IV recognition\n%s", DBar, DBar);
03317 Cfg()->Print(TFile);
03318 fprintf(TFile, "%sTrace in IV recognition\n%s", DBar, DBar );
03319 }
03320
03321
03322 BB_LOOP *loop_list = _cfg->Analyze_loops();
03323 #ifdef KEY
03324 #ifdef Is_True_On
03325 INT32 ivr_idx = 0;
03326 #endif
03327 #endif
03328 if (loop_list != NULL) {
03329 IVR iv_recog(this, trace_ivr);
03330 BB_LOOP_ITER loop_iter(loop_list);
03331 BB_LOOP *loop;
03332
03333 FOR_ALL_NODE(loop, loop_iter, Init()){
03334 #ifdef KEY
03335 #ifdef Is_True_On
03336 if (WOPT_Enable_Ivr_Limit != -1 && ivr_idx >= WOPT_Enable_Ivr_Limit)
03337 break;
03338 ivr_idx++;
03339 #endif
03340 #endif
03341 iv_recog.Process_one_loop(loop);
03342 }
03343
03344 if (iv_recog.Rebuild_loops()) {
03345
03346 _cfg->Invalidate_loops();
03347 _cfg->Analyze_loops();
03348 }
03349 }
03350
03351 if (trace_ivr) {
03352 fprintf(TFile, "%sDump after IV recognition\n%s", DBar, DBar );
03353 Cfg()->Print(TFile);
03354 }
03355 }
03356
03357
03358
03359
03360
03361
03362
03363
03364
03365
03366
03367 void
03368 IV_CAND::Print(FILE *fp) const
03369 {
03370 fprintf(fp, "IV_CAND: ");
03371 _phi->Print(_phi->Size(), fp);
03372 fprintf(fp, " Init");
03373 _init_var->Print(1, fp);
03374 fprintf(fp, " Step");
03375 _step_value->Print(15, fp);
03376 }
03377
03378
03379 void
03380 IVR::Print_all_iv_cand(FILE *fp)
03381 {
03382 vector<IV_CAND*>::iterator iv_cand_iter;
03383 for (iv_cand_iter = iv_cand_container.begin();
03384 iv_cand_iter != iv_cand_container.end();
03385 iv_cand_iter++) {
03386 IV_CAND *cur_iv = *iv_cand_iter;
03387 cur_iv->Print(fp);
03388 }
03389 }
03390
03391
03392