00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 #ifdef USE_PCH
00059 #include "cg_pch.h"
00060 #endif // USE_PCH
00061 #pragma hdrstop
00062
00063 #ifdef _KEEP_RCS_ID
00064 static const char source_file[] = __FILE__;
00065 #endif
00066
00067 #include <stdarg.h>
00068 #include "defs.h"
00069 #include "config_targ_opt.h"
00070 #include "errors.h"
00071 #include "mempool.h"
00072 #include "tracing.h"
00073 #include "timing.h"
00074 #include "cgir.h"
00075 #include "tn_map.h"
00076 #include "cg_loop.h"
00077 #include "cg.h"
00078 #include "cgexp.h"
00079 #include "register.h"
00080 #include "cg_region.h"
00081 #include "wn.h"
00082 #include "region_util.h"
00083 #include "op_list.h"
00084 #include "cgprep.h"
00085 #include "gtn_universe.h"
00086 #include "gtn_set.h"
00087 #include "cg_db_op.h"
00088 #include "whirl2ops.h"
00089 #include "cgtarget.h"
00090 #include "gra_live.h"
00091 #include "reg_live.h"
00092 #include "cflow.h"
00093 #include "cg_spill.h"
00094 #include "cgexp_internals.h"
00095 #include "data_layout.h"
00096 #include "cxx_hash.h"
00097
00098 #include "ebo.h"
00099 #include "ebo_info.h"
00100 #include "ebo_special.h"
00101 #include "ebo_util.h"
00102 #include "region_bb_util.h"
00103 #include "ipfec_options.h"
00104
00105 #define TRUNC_32(val) (val & 0x00000000ffffffffll)
00106
00107
00108 #define SEXT_32(val) (((INT64)(val) << 32) >> 32)
00109
00110 typedef HASH_TABLE<ST_IDX, INITV_IDX> ST_TO_INITV_MAP;
00111 static ST_TO_INITV_MAP *st_initv_map = NULL;
00112 static BOOL st_initv_map_inited = FALSE;
00113 static GTN_SET *work_gtn_set = NULL;
00114 static BS *work_defined_set = NULL;
00115 static MEM_POOL *work_pool = NULL;
00116
00117
00118
00119
00120
00121 #if 0
00122 void
00123 EBO_Special_Start (MEM_POOL *pool)
00124 {
00125 Init_Addr_Modes();
00126 }
00127 #endif
00128
00129 void
00130 EBO_Special_Finish (void)
00131 {
00132 st_initv_map = NULL;
00133 st_initv_map_inited = FALSE;
00134 work_gtn_set = NULL;
00135 work_defined_set = NULL;
00136 work_pool = NULL;
00137 }
00138
00139
00140
00141
00142
00143
00144 BOOL EBO_Can_Merge_Into_Offset (OP *op)
00145 {
00146 TN *tn;
00147
00148 if (!OP_iadd(op) && !OP_isub(op) && !OP_ior(op)) {
00149 return FALSE;
00150 }
00151 if ((op == BB_entry_sp_adj_op(OP_bb(op))) ||
00152 (op == BB_exit_sp_adj_op(OP_bb(op)))) {
00153 return FALSE;
00154 }
00155 tn = OP_opnd(op,1);
00156 if ((OP_iadd(op) || OP_ior(op)) && TN_Is_Constant(tn)) {
00157 return TRUE;
00158 }
00159 tn = OP_opnd(op,2);
00160 if ((OP_iadd(op) || OP_ior(op)) && TN_Is_Constant(tn)) {
00161 return TRUE;
00162 }
00163 return FALSE;
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 static
00176 INT
00177 EBO_bit_length (OP *op)
00178 {
00179 switch (OP_code(op))
00180 {
00181 case TOP_dep:
00182 { TN *length_tn = OP_opnd(op,4);
00183 if (TN_has_value(length_tn)) return TN_value(length_tn);
00184 return -1;
00185 }
00186 case TOP_dep_z:
00187 case TOP_extr:
00188 case TOP_extr_u:
00189 { TN *length_tn = OP_opnd(op,3);
00190 if (TN_has_value(length_tn)) return TN_value(length_tn);
00191 return -1;
00192 }
00193 case TOP_shr_i:
00194 case TOP_shr_i_u:
00195 { TN *length_tn = OP_opnd(op,2);
00196 if (TN_has_value(length_tn)) return (64-TN_value(length_tn));
00197 return -1;
00198 }
00199 case TOP_ld1:
00200 case TOP_ld1_i:
00201 case TOP_st1:
00202 case TOP_st1_i:
00203 case TOP_sxt1:
00204 case TOP_zxt1:
00205 return 8;
00206 case TOP_ld2:
00207 case TOP_ld2_i:
00208 case TOP_st2:
00209 case TOP_st2_i:
00210 case TOP_sxt2:
00211 case TOP_zxt2:
00212 return 16;
00213 case TOP_cmp4_eq:
00214 case TOP_cmp4_eq_unc:
00215 case TOP_cmp4_eq_and:
00216 case TOP_cmp4_eq_or:
00217 case TOP_cmp4_eq_or_andcm:
00218 case TOP_cmp4_ne_and:
00219 case TOP_cmp4_ne_or:
00220 case TOP_cmp4_ne_or_andcm:
00221 case TOP_cmp4_lt:
00222 case TOP_cmp4_lt_unc:
00223 case TOP_cmp4_ltu:
00224 case TOP_cmp4_ltu_unc:
00225 case TOP_cmp4_z1_lt_and:
00226 case TOP_cmp4_z1_lt_or:
00227 case TOP_cmp4_z1_lt_or_andcm:
00228 case TOP_cmp4_z1_le_and:
00229 case TOP_cmp4_z1_le_or:
00230 case TOP_cmp4_z1_le_or_andcm:
00231 case TOP_cmp4_z1_gt_and:
00232 case TOP_cmp4_z1_gt_or:
00233 case TOP_cmp4_z1_gt_or_andcm:
00234 case TOP_cmp4_z1_ge_and:
00235 case TOP_cmp4_z1_ge_or:
00236 case TOP_cmp4_z1_ge_or_andcm:
00237 case TOP_cmp4_i_eq:
00238 case TOP_cmp4_i_eq_unc:
00239 case TOP_cmp4_i_eq_and:
00240 case TOP_cmp4_i_eq_or:
00241 case TOP_cmp4_i_eq_or_andcm:
00242 case TOP_cmp4_i_ne_and:
00243 case TOP_cmp4_i_ne_or:
00244 case TOP_cmp4_i_ne_or_andcm:
00245 case TOP_cmp4_i_lt:
00246 case TOP_cmp4_i_lt_unc:
00247 case TOP_cmp4_i_ltu:
00248 case TOP_cmp4_i_ltu_unc:
00249 case TOP_cmp4_eq_orcm:
00250 case TOP_cmp4_eq_andcm:
00251 case TOP_cmp4_eq_and_orcm:
00252 case TOP_cmp4_ne:
00253 case TOP_cmp4_ne_unc:
00254 case TOP_cmp4_ne_orcm:
00255 case TOP_cmp4_ne_andcm:
00256 case TOP_cmp4_ne_and_orcm:
00257 case TOP_cmp4_le:
00258 case TOP_cmp4_le_unc:
00259 case TOP_cmp4_gt:
00260 case TOP_cmp4_gt_unc:
00261 case TOP_cmp4_ge:
00262 case TOP_cmp4_ge_unc:
00263 case TOP_cmp4_leu:
00264 case TOP_cmp4_leu_unc:
00265 case TOP_cmp4_gtu:
00266 case TOP_cmp4_gtu_unc:
00267 case TOP_cmp4_geu:
00268 case TOP_cmp4_geu_unc:
00269 case TOP_cmp4_z1_lt_orcm:
00270 case TOP_cmp4_z1_lt_andcm:
00271 case TOP_cmp4_z1_lt_and_orcm:
00272 case TOP_cmp4_z1_le_orcm:
00273 case TOP_cmp4_z1_le_andcm:
00274 case TOP_cmp4_z1_le_and_orcm:
00275 case TOP_cmp4_z1_gt_orcm:
00276 case TOP_cmp4_z1_gt_andcm:
00277 case TOP_cmp4_z1_gt_and_orcm:
00278 case TOP_cmp4_z1_ge_orcm:
00279 case TOP_cmp4_z1_ge_andcm:
00280 case TOP_cmp4_z1_ge_and_orcm:
00281 case TOP_cmp4_z2_lt_orcm:
00282 case TOP_cmp4_z2_lt_andcm:
00283 case TOP_cmp4_z2_lt_and_orcm:
00284 case TOP_cmp4_z2_le_orcm:
00285 case TOP_cmp4_z2_le_andcm:
00286 case TOP_cmp4_z2_le_and_orcm:
00287 case TOP_cmp4_z2_gt_orcm:
00288 case TOP_cmp4_z2_gt_andcm:
00289 case TOP_cmp4_z2_gt_and_orcm:
00290 case TOP_cmp4_z2_ge_orcm:
00291 case TOP_cmp4_z2_ge_andcm:
00292 case TOP_cmp4_z2_ge_and_orcm:
00293 case TOP_cmp4_z2_lt_and:
00294 case TOP_cmp4_z2_lt_or:
00295 case TOP_cmp4_z2_lt_or_andcm:
00296 case TOP_cmp4_z2_le_and:
00297 case TOP_cmp4_z2_le_or:
00298 case TOP_cmp4_z2_le_or_andcm:
00299 case TOP_cmp4_z2_gt_and:
00300 case TOP_cmp4_z2_gt_or:
00301 case TOP_cmp4_z2_gt_or_andcm:
00302 case TOP_cmp4_z2_ge_and:
00303 case TOP_cmp4_z2_ge_or:
00304 case TOP_cmp4_z2_ge_or_andcm:
00305 case TOP_cmp4_i_eq_orcm:
00306 case TOP_cmp4_i_eq_andcm:
00307 case TOP_cmp4_i_eq_and_orcm:
00308 case TOP_cmp4_i_ne:
00309 case TOP_cmp4_i_ne_unc:
00310 case TOP_cmp4_i_ne_orcm:
00311 case TOP_cmp4_i_ne_andcm:
00312 case TOP_cmp4_i_ne_and_orcm:
00313 case TOP_cmp4_i_le:
00314 case TOP_cmp4_i_le_unc:
00315 case TOP_cmp4_i_gt:
00316 case TOP_cmp4_i_gt_unc:
00317 case TOP_cmp4_i_ge:
00318 case TOP_cmp4_i_ge_unc:
00319 case TOP_cmp4_i_leu:
00320 case TOP_cmp4_i_leu_unc:
00321 case TOP_cmp4_i_gtu:
00322 case TOP_cmp4_i_gtu_unc:
00323 case TOP_cmp4_i_geu:
00324 case TOP_cmp4_i_geu_unc:
00325 case TOP_cmp4_lt_and:
00326 case TOP_cmp4_lt_or:
00327 case TOP_cmp4_lt_or_andcm:
00328 case TOP_cmp4_le_and:
00329 case TOP_cmp4_le_or:
00330 case TOP_cmp4_le_or_andcm:
00331 case TOP_cmp4_gt_and:
00332 case TOP_cmp4_gt_or:
00333 case TOP_cmp4_gt_or_andcm:
00334 case TOP_cmp4_ge_and:
00335 case TOP_cmp4_ge_or:
00336 case TOP_cmp4_ge_or_andcm:
00337 case TOP_cmp4_lt_orcm:
00338 case TOP_cmp4_lt_andcm:
00339 case TOP_cmp4_lt_and_orcm:
00340 case TOP_cmp4_le_orcm:
00341 case TOP_cmp4_le_andcm:
00342 case TOP_cmp4_le_and_orcm:
00343 case TOP_cmp4_gt_orcm:
00344 case TOP_cmp4_gt_andcm:
00345 case TOP_cmp4_gt_and_orcm:
00346 case TOP_cmp4_ge_orcm:
00347 case TOP_cmp4_ge_andcm:
00348 case TOP_cmp4_ge_and_orcm:
00349 case TOP_ld4:
00350 case TOP_ld4_i:
00351 case TOP_st4:
00352 case TOP_st4_i:
00353 case TOP_sxt4:
00354 case TOP_zxt4:
00355 return 32;
00356 case TOP_and_i: {
00357
00358 if (TN_has_value(OP_opnd(op,1))) {
00359
00360
00361 switch (TN_value(OP_opnd(op,1))) {
00362 case 1: return 1;
00363 case 3: return 2;
00364 case 7: return 3;
00365 case 15: return 4;
00366 case 31: return 5;
00367 case 63: return 6;
00368 case 127: return 7;
00369 case 255: return 64;
00370 default: return -1;
00371 }
00372
00373 }
00374
00375 }
00376 }
00377
00378 return -1;
00379 }
00380
00381
00382
00383
00384 static
00385 INT
00386 Get_Right_Mask_Length (UINT64 mask)
00387
00388
00389
00390
00391
00392
00393 {
00394 INT64 i;
00395
00396 if (mask == 0) return -1;
00397 if ((mask & 1) == 0) return -1;
00398
00399 for ( i = 1; i < 64; i++)
00400 {
00401 if (((mask >> i) & 1) == 0) return ((mask >> i) == 0) ? i : -1;
00402 }
00403
00404 return -1;
00405 }
00406
00407
00408
00409 static
00410 INT
00411 Get_Mask_Shift_Count (UINT64 mask)
00412
00413
00414
00415
00416
00417 {
00418 INT64 i;
00419
00420 if (mask == 0) return -1;
00421
00422 for ( i = 0; i < 63; i++)
00423 {
00424 if ((mask & (1 << i)) != 0) return i;
00425 }
00426
00427 return -1;
00428 }
00429
00430
00431
00432
00433 static
00434 BOOL
00435 TOP_Is_Unconditional_Compare (TOP opcode)
00436 {
00437 return ((opcode == TOP_tnat_nz_unc) ||
00438 (opcode == TOP_tnat_z_unc) ||
00439 (opcode == TOP_cmp_eq_unc) ||
00440 (opcode == TOP_cmp_ge_unc) ||
00441 (opcode == TOP_cmp_geu_unc) ||
00442 (opcode == TOP_cmp_gt_unc) ||
00443 (opcode == TOP_cmp_gtu_unc) ||
00444 (opcode == TOP_cmp_le_unc) ||
00445 (opcode == TOP_cmp_leu_unc) ||
00446 (opcode == TOP_cmp_lt_unc) ||
00447 (opcode == TOP_cmp_ltu_unc) ||
00448 (opcode == TOP_cmp_ne_unc) ||
00449 (opcode == TOP_cmp4_eq_unc) ||
00450 (opcode == TOP_cmp4_ge_unc) ||
00451 (opcode == TOP_cmp4_geu_unc) ||
00452 (opcode == TOP_cmp4_gt_unc) ||
00453 (opcode == TOP_cmp4_gtu_unc) ||
00454 (opcode == TOP_cmp4_le_unc) ||
00455 (opcode == TOP_cmp4_leu_unc) ||
00456 (opcode == TOP_cmp4_lt_unc) ||
00457 (opcode == TOP_cmp4_ltu_unc) ||
00458 (opcode == TOP_cmp4_ne_unc) ||
00459 (opcode == TOP_cmp4_i_eq_unc) ||
00460 (opcode == TOP_cmp4_i_ge_unc) ||
00461 (opcode == TOP_cmp4_i_geu_unc) ||
00462 (opcode == TOP_cmp4_i_gt_unc) ||
00463 (opcode == TOP_cmp4_i_gtu_unc) ||
00464 (opcode == TOP_cmp4_i_le_unc) ||
00465 (opcode == TOP_cmp4_i_leu_unc) ||
00466 (opcode == TOP_cmp4_i_lt_unc) ||
00467 (opcode == TOP_cmp4_i_ltu_unc) ||
00468 (opcode == TOP_cmp4_i_ne_unc) ||
00469 (opcode == TOP_cmp_i_eq_unc) ||
00470 (opcode == TOP_cmp_i_ge_unc) ||
00471 (opcode == TOP_cmp_i_geu_unc) ||
00472 (opcode == TOP_cmp_i_gt_unc) ||
00473 (opcode == TOP_cmp_i_gtu_unc) ||
00474 (opcode == TOP_cmp_i_le_unc) ||
00475 (opcode == TOP_cmp_i_leu_unc) ||
00476 (opcode == TOP_cmp_i_lt_unc) ||
00477 (opcode == TOP_cmp_i_ltu_unc) ||
00478 (opcode == TOP_cmp_i_ne_unc) ||
00479 (opcode == TOP_fclass_m_unc) ||
00480 (opcode == TOP_fclass_nm_unc) ||
00481 (opcode == TOP_tbit_nz_unc) ||
00482 (opcode == TOP_tbit_z_unc) ||
00483 (opcode == TOP_fcmp_eq_unc) ||
00484 (opcode == TOP_fcmp_ge_unc) ||
00485 (opcode == TOP_fcmp_gt_unc) ||
00486 (opcode == TOP_fcmp_le_unc) ||
00487 (opcode == TOP_fcmp_lt_unc) ||
00488 (opcode == TOP_fcmp_neq_unc) ||
00489 (opcode == TOP_fcmp_nge_unc) ||
00490 (opcode == TOP_fcmp_ngt_unc) ||
00491 (opcode == TOP_fcmp_nle_unc) ||
00492 (opcode == TOP_fcmp_nlt_unc) ||
00493 (opcode == TOP_fcmp_ord_unc) ||
00494 (opcode == TOP_fcmp_unord_unc));
00495 }
00496
00497
00498
00499
00500 static
00501 void
00502 EBO_Set_OP_omega (OP *op, ...)
00503 {
00504 INT opnds = OP_opnds(op);
00505 INT i;
00506 va_list tninfos;
00507
00508 va_start(tninfos, op);
00509 CG_LOOP_Init_Op(op);
00510 for (i = 0; i < opnds; i++) {
00511 EBO_TN_INFO *tninfo = va_arg(tninfos, EBO_TN_INFO *);
00512 Set_OP_omega (op, i, ((tninfo != NULL) ? tninfo->omega : 0));
00513 }
00514
00515 va_end(tninfos);
00516 return;
00517 }
00518
00519
00520
00521 static
00522 void
00523 EBO_Copy_OP_omega (OP *new_op, OP *old_op)
00524 {
00525 INT opnds = OP_opnds(new_op);
00526 INT i;
00527
00528 CG_LOOP_Init_Op(new_op);
00529 for (i = 0; i < opnds; i++) {
00530 Set_OP_omega (new_op, i, OP_omega(old_op,i));
00531 }
00532
00533 return;
00534 }
00535
00536
00537 static
00538 void
00539 EBO_Set_Predicate_omega (OP *new_op, EBO_TN_INFO *pred_tninfo)
00540 {
00541 if (pred_tninfo != NULL) {
00542 Set_OP_omega (new_op, OP_PREDICATE_OPND, pred_tninfo->omega);
00543 }
00544 return;
00545 }
00546
00547
00548 static
00549 void
00550 EBO_OPS_omega (OPS *ops, EBO_TN_INFO *pred_tninfo)
00551 {
00552 OP *next_op = OPS_first(ops);
00553 while (next_op != NULL) {
00554 INT opnds = OP_opnds(next_op);
00555 INT i;
00556
00557 CG_LOOP_Init_Op(next_op);
00558 for (i = 0; i < opnds; i++) {
00559 Set_OP_omega (next_op, i, 0);
00560 }
00561
00562 if (OP_has_predicate(next_op) && (pred_tninfo != NULL)) {
00563 Set_OP_omega(next_op, OP_PREDICATE_OPND, pred_tninfo->omega);
00564 }
00565 next_op = OP_next(next_op);
00566 }
00567
00568 return;
00569 }
00570
00571
00572
00573
00574 static
00575 void
00576 EBO_Copy_Predicate(TN *predicate_tn, TN *source_tn, OPS *ops)
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588 {
00589 TN *result1 = True_TN;
00590 TN *result2 = True_TN;
00591 TN *predicate = True_TN;
00592
00593 if (source_tn == True_TN) {
00594 result1 = predicate_tn;
00595 } else if (TN_Is_Constant(source_tn)) {
00596 result2 = predicate_tn;
00597 } else {
00598 result1 = predicate_tn;
00599 predicate = source_tn;
00600 }
00601
00602 Build_OP (TOP_cmp_eq_unc, result1, result2, predicate, Zero_TN, Zero_TN, ops);
00603 }
00604
00605
00606
00607 static
00608 void
00609 EBO_Complement_Predicate(TN *predicate_tn, TN *source_tn, OPS *ops)
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621 {
00622 TN *result1 = True_TN;
00623 TN *result2 = True_TN;
00624 TN *predicate = True_TN;
00625
00626 if (source_tn == True_TN) {
00627 result1 = predicate_tn;
00628 } else if (TN_is_constant(source_tn)) {
00629 result2 = predicate_tn;
00630 } else {
00631 result1 = predicate_tn;
00632 predicate = source_tn;
00633 }
00634
00635 Build_OP (TOP_cmp_eq_unc, result2, result1, predicate, Zero_TN, Zero_TN, ops);
00636 }
00637
00638
00639
00640 static
00641 BOOL
00642 condition_redundant(OP *elim_op,
00643 EBO_TN_INFO **opnd_tninfo,
00644 EBO_OP_INFO *prev_opinfo)
00645 {
00646 OP *prev_op = prev_opinfo->in_op;
00647 OPS ops = OPS_EMPTY;
00648 TOP p_opcode = OP_code(prev_op);
00649 TOP e_opcode = OP_code(elim_op);
00650
00651 if ((p_opcode == e_opcode) ||
00652 ((p_opcode == TOP_cmp_eq) && (e_opcode == TOP_cmp_ne)) ||
00653 ((p_opcode == TOP_cmp_i_eq) && (e_opcode == TOP_cmp_i_ne)) ||
00654 ((p_opcode == TOP_cmp_eq_unc) && (e_opcode == TOP_cmp_ne_unc)) ||
00655 ((p_opcode == TOP_cmp_i_eq_unc) && (e_opcode == TOP_cmp_i_ne_unc)) ||
00656 ((p_opcode == TOP_cmp4_eq) && (e_opcode == TOP_cmp4_ne)) ||
00657 ((p_opcode == TOP_cmp4_i_eq) && (e_opcode == TOP_cmp4_i_ne)) ||
00658 ((p_opcode == TOP_cmp4_eq_unc) && (e_opcode == TOP_cmp4_ne_unc)) ||
00659 ((p_opcode == TOP_cmp4_i_eq_unc) && (e_opcode == TOP_cmp4_i_ne_unc)) ||
00660 ((p_opcode == TOP_cmp_ne) && (e_opcode == TOP_cmp_eq)) ||
00661 ((p_opcode == TOP_cmp_i_ne) && (e_opcode == TOP_cmp_i_eq)) ||
00662 ((p_opcode == TOP_cmp_ne_unc) && (e_opcode == TOP_cmp_eq_unc)) ||
00663 ((p_opcode == TOP_cmp_i_ne_unc) && (e_opcode == TOP_cmp_i_eq_unc)) ||
00664 ((p_opcode == TOP_cmp4_ne) && (e_opcode == TOP_cmp4_eq)) ||
00665 ((p_opcode == TOP_cmp4_i_ne) && (e_opcode == TOP_cmp4_i_eq)) ||
00666 ((p_opcode == TOP_cmp4_ne_unc) && (e_opcode == TOP_cmp4_eq_unc)) ||
00667 ((p_opcode == TOP_cmp4_i_ne_unc) && (e_opcode == TOP_cmp4_i_eq_unc)) ||
00668 ((p_opcode == TOP_cmp_le) && (e_opcode == TOP_cmp_gt)) ||
00669 ((p_opcode == TOP_cmp_i_le) && (e_opcode == TOP_cmp_i_gt)) ||
00670 ((p_opcode == TOP_cmp_le_unc) && (e_opcode == TOP_cmp_gt_unc)) ||
00671 ((p_opcode == TOP_cmp_i_le_unc) && (e_opcode == TOP_cmp_i_gt_unc)) ||
00672 ((p_opcode == TOP_cmp4_le) && (e_opcode == TOP_cmp4_gt)) ||
00673 ((p_opcode == TOP_cmp4_i_le) && (e_opcode == TOP_cmp4_i_gt)) ||
00674 ((p_opcode == TOP_cmp4_le_unc) && (e_opcode == TOP_cmp4_gt_unc)) ||
00675 ((p_opcode == TOP_cmp4_i_le_unc) && (e_opcode == TOP_cmp4_i_gt_unc)) ||
00676 ((p_opcode == TOP_cmp_gt) && (e_opcode == TOP_cmp_le)) ||
00677 ((p_opcode == TOP_cmp_i_gt) && (e_opcode == TOP_cmp_i_le)) ||
00678 ((p_opcode == TOP_cmp_gt_unc) && (e_opcode == TOP_cmp_le_unc)) ||
00679 ((p_opcode == TOP_cmp_i_gt_unc) && (e_opcode == TOP_cmp_i_le_unc)) ||
00680 ((p_opcode == TOP_cmp4_gt) && (e_opcode == TOP_cmp4_le)) ||
00681 ((p_opcode == TOP_cmp4_i_gt) && (e_opcode == TOP_cmp4_i_le)) ||
00682 ((p_opcode == TOP_cmp4_gt_unc) && (e_opcode == TOP_cmp4_le_unc)) ||
00683 ((p_opcode == TOP_cmp4_i_gt_unc) && (e_opcode == TOP_cmp4_i_le_unc)) ||
00684 ((p_opcode == TOP_cmp_lt) && (e_opcode == TOP_cmp_ge)) ||
00685 ((p_opcode == TOP_cmp_i_lt) && (e_opcode == TOP_cmp_i_ge)) ||
00686 ((p_opcode == TOP_cmp_lt_unc) && (e_opcode == TOP_cmp_ge_unc)) ||
00687 ((p_opcode == TOP_cmp_i_lt_unc) && (e_opcode == TOP_cmp_i_ge_unc)) ||
00688 ((p_opcode == TOP_cmp4_lt) && (e_opcode == TOP_cmp4_ge)) ||
00689 ((p_opcode == TOP_cmp4_i_lt) && (e_opcode == TOP_cmp4_i_ge)) ||
00690 ((p_opcode == TOP_cmp4_lt_unc) && (e_opcode == TOP_cmp4_ge_unc)) ||
00691 ((p_opcode == TOP_cmp4_i_lt_unc) && (e_opcode == TOP_cmp4_i_ge_unc)) ||
00692 ((p_opcode == TOP_cmp_ge) && (e_opcode == TOP_cmp_lt)) ||
00693 ((p_opcode == TOP_cmp_i_ge) && (e_opcode == TOP_cmp_i_lt)) ||
00694 ((p_opcode == TOP_cmp_ge_unc) && (e_opcode == TOP_cmp_lt_unc)) ||
00695 ((p_opcode == TOP_cmp_i_ge_unc) && (e_opcode == TOP_cmp_i_lt_unc)) ||
00696 ((p_opcode == TOP_cmp4_ge) && (e_opcode == TOP_cmp4_lt)) ||
00697 ((p_opcode == TOP_cmp4_i_ge) && (e_opcode == TOP_cmp4_i_lt)) ||
00698 ((p_opcode == TOP_cmp4_ge_unc) && (e_opcode == TOP_cmp4_lt_unc)) ||
00699 ((p_opcode == TOP_cmp4_i_ge_unc) && (e_opcode == TOP_cmp4_i_lt_unc))) {
00700 TN *pr0 = OP_result(prev_op,0);
00701 TN *pr1 = OP_result(prev_op,1);
00702 EBO_TN_INFO *pr0_tninfo = prev_opinfo->actual_rslt[0];
00703 EBO_TN_INFO *pr1_tninfo = prev_opinfo->actual_rslt[1];
00704 TN *er0 = OP_result(elim_op,0);
00705 TN *er1 = OP_result(elim_op,1);
00706 TN *prp = OP_opnd(prev_op,OP_PREDICATE_OPND);
00707 TN *erp = OP_opnd(elim_op,OP_PREDICATE_OPND);
00708
00709 if (p_opcode != e_opcode) {
00710
00711 TN *save_tn = pr0;
00712 EBO_TN_INFO *save_tn_info = pr0_tninfo;
00713
00714 if (((pr0 == True_TN) && (er0 == True_TN)) ||
00715 ((pr1 == True_TN) && (er1 == True_TN))) {
00716
00717
00718 if (prp != erp) goto can_not_combine_ops;
00719
00720 for (INT i = 0; i < OP_results(prev_op); i++) {
00721 if (!TN_Is_Constant(OP_result(prev_op,i))) {
00722 EBO_TN_INFO *result_tninfo = prev_opinfo->actual_rslt[i];
00723 if ((result_tninfo == NULL) ||
00724 (result_tninfo->reference_count != 0)) goto can_not_combine_ops;
00725 }
00726 }
00727 if ( pr0 == True_TN ) {
00728 if ( (TN_register_class(pr1) == TN_register_class(er1))
00729 && (TN_register(pr1) == TN_register(er1)))
00730 goto can_not_combine_ops;
00731 } else {
00732 if ( (TN_register_class(pr0) == TN_register_class(er0))
00733 && (TN_register(pr0) == TN_register(er0)))
00734 goto can_not_combine_ops;
00735 }
00736
00737 OP *new_op = Dup_OP(elim_op);
00738 if (pr0 == True_TN) {
00739 Set_OP_result(new_op, 0, pr1);
00740 } else {
00741 Set_OP_result(new_op, 1, pr0);
00742 }
00743 if (EBO_in_loop) EBO_Copy_OP_omega (new_op, elim_op);
00744 OP_srcpos(new_op) = OP_srcpos(elim_op);
00745 BB_Insert_Op_After(OP_bb(elim_op), elim_op, new_op);
00746
00747 if (EBO_Trace_Optimization) {
00748 #pragma mips_frequency_hint NEVER
00749 fprintf(TFile,"%sMerge complementery compare operations.\n",EBO_trace_pfx);
00750 }
00751
00752 return TRUE;
00753 }
00754
00755
00756 save_tn = pr0;
00757 pr0 = pr1;
00758 pr1 = save_tn;
00759
00760 save_tn_info = pr0_tninfo;
00761 pr0_tninfo = pr1_tninfo;
00762 pr1_tninfo = save_tn_info;
00763 if (EBO_Trace_Optimization) {
00764 #pragma mips_frequency_hint NEVER
00765 fprintf(TFile,"%sCompare instructions are complements.\n",EBO_trace_pfx);
00766 }
00767 }
00768
00769 if ((prp != erp) ||
00770 (EBO_in_pre &&
00771 (OP_bb(prev_op) != OP_bb(elim_op)))) {
00772
00773
00774
00775
00776
00777
00778 if (EBO_Trace_Optimization) {
00779 #pragma mips_frequency_hint NEVER
00780 fprintf(TFile,"%sPredicates are different for redundant compare.\n",EBO_trace_pfx);
00781 }
00782
00783 goto can_not_combine_ops;
00784 }
00785
00786
00787 if (((er0 != True_TN) && tn_registers_identical (er0, pr1)) ||
00788 ((er1 != True_TN) && tn_registers_identical (er1, pr0))) {
00789
00790 if (EBO_Trace_Optimization) {
00791 #pragma mips_frequency_hint NEVER
00792 fprintf(TFile,"%sRegister re-use in redundant compare.\n",EBO_trace_pfx);
00793 }
00794
00795 goto can_not_combine_ops;
00796 }
00797
00798
00799 if (tn_registers_identical (er0, pr0) &&
00800 tn_registers_identical (er1, pr1)) {
00801 if (EBO_Trace_Optimization) {
00802 #pragma mips_frequency_hint NEVER
00803 fprintf(TFile,"%sDelete redundant compare operation.\n",EBO_trace_pfx);
00804 }
00805
00806 return TRUE;
00807 }
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817 if (er0 != True_TN) {
00818 if (pr0 != True_TN && EBO_tn_available(OP_bb(elim_op), pr0_tninfo)) {
00819 EBO_Copy_Predicate (er0, pr0, &ops);
00820 } else {
00821 goto can_not_combine_ops;
00822 }
00823 }
00824 if (er1 != True_TN) {
00825 if (pr1 != True_TN && EBO_tn_available(OP_bb(elim_op), pr1_tninfo)) {
00826 EBO_Copy_Predicate (er1, pr1, &ops);
00827 } else {
00828 goto can_not_combine_ops;
00829 }
00830 }
00831
00832 if (OPS_length(&ops) != 0) {
00833 if (EBO_in_loop) EBO_OPS_omega (&ops, NULL);
00834 OP *next_op = OPS_first(&ops);
00835 while (next_op != NULL) {
00836 OP_srcpos(next_op) = OP_srcpos(elim_op);
00837 next_op = OP_next(next_op);
00838 }
00839 BB_Insert_Ops(OP_bb(elim_op), elim_op, &ops, FALSE);
00840 }
00841
00842 if (EBO_Trace_Optimization) {
00843 #pragma mips_frequency_hint NEVER
00844 fprintf(TFile,"%sRemove redundant compare operation.\n",EBO_trace_pfx);
00845 }
00846
00847 return TRUE;
00848 }
00849
00850 can_not_combine_ops:
00851
00852 if (EBO_Trace_Optimization) {
00853 #pragma mips_frequency_hint NEVER
00854 fprintf(TFile,"%sCan not remove compare operation.\n",EBO_trace_pfx);
00855 }
00856
00857 return FALSE;
00858 }
00859
00860
00861
00862
00863 BOOL
00864 combine_adjacent_loads(OP *op,
00865 EBO_TN_INFO **opnd_tninfo,
00866 EBO_OP_INFO *opinfo,
00867 INT64 offset_pred,
00868 INT64 offset_succ)
00869 {
00870 OP *pred_op = opinfo->in_op;
00871 BB *bb = OP_bb(op);
00872 TOP opcode = OP_code(op);
00873 TOP new_opcode;
00874 TN *pred_result = OP_result(pred_op,0);
00875 TN *succ_result = OP_result(op,0);
00876 INT base_index = TOP_Find_Operand_Use(OP_code(op),OU_base);
00877 TN *base_tn;
00878 EBO_TN_INFO *base_tninfo;
00879 INT size_pred;
00880 INT size_succ;
00881 TN *r1;
00882 TN *r2;
00883 OPS ops = OPS_EMPTY;
00884
00885 if (EBO_Trace_Data_Flow) {
00886 fprintf(TFile,"%s OP in BB:%d ",EBO_trace_pfx,BB_id(bb));
00887 Print_OP_No_SrcLine(op);
00888 fprintf(TFile," is adjacent to OP in BB:%d ",BB_id(opinfo->in_bb));
00889 Print_OP_No_SrcLine(pred_op);
00890 }
00891
00892
00893 if (!OP_load(op) || !OP_load(pred_op) || (opcode != OP_code(pred_op)) ||
00894 (OP_results(op) != 1) || (OP_results(pred_op) != 1) || (base_index < 0) ||
00895
00896
00897
00898 CGTARG_Is_OP_Speculative(op) || CGTARG_Is_OP_Speculative(pred_op) ||
00899 CGTARG_Is_OP_Check_Load(op) || CGTARG_Is_OP_Check_Load(pred_op) ||
00900 BB_recovery(OP_bb(op)) || BB_recovery(OP_bb(pred_op))) {
00901 return FALSE;
00902 }
00903
00904 if ((Opt_Level < 2) && (bb != opinfo->in_bb)) {
00905
00906 return FALSE;
00907 }
00908
00909 size_pred = CGTARG_Mem_Ref_Bytes(pred_op);
00910 size_succ = CGTARG_Mem_Ref_Bytes(op);
00911 if (size_pred != size_succ) return FALSE;
00912
00913 if (!EBO_in_peep &&
00914 (bb != opinfo->in_bb) &&
00915 !TN_Is_Constant(pred_result) &&
00916 has_assigned_reg(pred_result)) {
00917 if (EBO_Trace_Data_Flow) {
00918 #pragma mips_frequency_hint NEVER
00919 fprintf(TFile,"%sShouldn't move dedicated register references across blocks.\n",
00920 EBO_trace_pfx);
00921 }
00922 return FALSE;
00923 }
00924
00925 if (!has_assigned_reg(pred_result) ||
00926 !has_assigned_reg(succ_result) ||
00927 (TN_register_class(pred_result) != TN_register_class(succ_result)) ||
00928 ((TN_register(pred_result) & 1) == (TN_register(succ_result) & 1))) {
00929 if (EBO_Trace_Data_Flow) {
00930 #pragma mips_frequency_hint NEVER
00931 fprintf(TFile,"%sParied loads requires odd/even registers.\n", EBO_trace_pfx);
00932 }
00933 return FALSE;
00934 }
00935
00936 if ((opinfo->actual_rslt[0] == NULL) ||
00937 (opinfo->actual_rslt[0]->reference_count != 0) ||
00938 !EBO_tn_available (opinfo->in_bb, opinfo->actual_rslt[0])) {
00939 if (EBO_Trace_Data_Flow) {
00940 #pragma mips_frequency_hint NEVER
00941 fprintf(TFile,"%sThe result of the predecessor load has already been used.\n", EBO_trace_pfx);
00942 }
00943 return FALSE;
00944 }
00945
00946 switch (opcode) {
00947 case TOP_ldfs: new_opcode = TOP_ldfps; break;
00948 case TOP_ldfd: new_opcode = TOP_ldfpd; break;
00949 case TOP_ldf8: new_opcode = TOP_ldfp8; break;
00950 default: return FALSE;
00951 }
00952
00953 if (offset_pred < offset_succ) {
00954 base_tn = OP_opnd(pred_op, base_index);
00955 base_tninfo = opinfo->actual_opnd[base_index];
00956 if (!TN_Is_Constant(base_tn) && !EBO_tn_available (opinfo->in_bb, base_tninfo)) {
00957 if (EBO_Trace_Data_Flow) {
00958 #pragma mips_frequency_hint NEVER
00959 fprintf(TFile,"%sThe index TN of the predecessor load is not available.\n", EBO_trace_pfx);
00960 }
00961 return FALSE;
00962 }
00963 r1 = pred_result;
00964 r2 = succ_result;
00965 } else {
00966 base_tn = OP_opnd(op, base_index);
00967 base_tninfo = opnd_tninfo[base_index];
00968 r1 = succ_result;
00969 r2 = pred_result;
00970 }
00971
00972
00973 if (EBO_Trace_Optimization) {
00974 #pragma mips_frequency_hint NEVER
00975 fprintf(TFile,"%sThe simulator does not yet support load-pair instructions.\n",EBO_trace_pfx);
00976 }
00977 return FALSE;
00978
00979 Build_OP (new_opcode, r1, r2, OP_opnd(op,OP_PREDICATE_OPND),
00980 OP_opnd(op,1), OP_opnd(op,2), base_tn, &ops);
00981 Copy_WN_For_Memory_OP (OPS_first(&ops), op);
00982 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
00983 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops), opnd_tninfo[OP_PREDICATE_OPND],
00984 NULL, NULL, base_tninfo);
00985 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
00986
00987 remove_op (opinfo);
00988 OP_Change_To_Noop(pred_op);
00989 opinfo->in_op = NULL;
00990 opinfo->in_bb = NULL;
00991
00992 if (EBO_Trace_Optimization) {
00993 #pragma mips_frequency_hint NEVER
00994 fprintf(TFile,"%sReplace adjacent load with load pair.\n",EBO_trace_pfx);
00995 }
00996
00997 return TRUE;
00998 }
00999
01000
01001
01002 static
01003 BOOL
01004 hoist_predicate_of_duplicate_complement (OP *op,
01005 EBO_TN_INFO **opnd_tninfo,
01006 EBO_OP_INFO *opinfo)
01007 {
01008 OP *pred_op = opinfo->in_op;
01009 TN *predicate1_tn = OP_opnd(pred_op,OP_PREDICATE_OPND);
01010 TN *predicate2_tn = OP_opnd(op,OP_PREDICATE_OPND);
01011 EBO_TN_INFO *predicate1_info = opinfo->actual_opnd[OP_PREDICATE_OPND];
01012 EBO_TN_INFO *predicate2_info = opnd_tninfo[OP_PREDICATE_OPND];
01013 BB *bb = OP_bb(op);
01014 INT i;
01015 INT val_idx;
01016
01017 if (EBO_Trace_Data_Flow) {
01018 fprintf(TFile,"Enter hoist_predicate_of_duplicate_complement\n");
01019 Print_OP_No_SrcLine(pred_op);
01020 Print_OP_No_SrcLine(op);
01021 Print_TN(predicate1_tn,false);fprintf(TFile," ");
01022 Print_TN(predicate2_tn,false);fprintf(TFile,"\n");
01023 if (predicate1_info != NULL) tn_info_entry_dump(predicate1_info);
01024 if (predicate2_info != NULL) tn_info_entry_dump(predicate2_info);
01025 }
01026
01027 if (OP_code(op) != OP_code(pred_op)) return FALSE;
01028
01029
01030 EBO_OP_INFO *new_predicate_opinfo = locate_opinfo_entry(predicate1_info);
01031 if (new_predicate_opinfo == NULL) return FALSE;
01032
01033 EBO_TN_INFO *new_predicate_tninfo = new_predicate_opinfo->actual_opnd[OP_PREDICATE_OPND];
01034 TN *new_predicate_tn = OP_opnd(predicate1_info->in_op,OP_PREDICATE_OPND);
01035
01036 if (!(TN_Is_Constant(new_predicate_tn) ||
01037 EBO_tn_available (bb, new_predicate_tninfo))) return FALSE;
01038
01039 if (OP_store(op)) {
01040
01041
01042 if (OP_bb(op) != OP_bb(pred_op)) return FALSE;
01043 if (opinfo->op_must_not_be_removed) return FALSE;
01044
01045 val_idx = TOP_Find_Operand_Use(OP_code(op),OU_storeval);
01046 EBO_TN_INFO *value_tninfo = opinfo->actual_opnd[val_idx];
01047
01048
01049
01050 if ((value_tninfo == NULL) ||
01051 !EBO_tn_available (bb, value_tninfo)) return FALSE;
01052
01053 if (TN_is_const_reg(OP_opnd(op, val_idx))) return FALSE;
01054
01055 if (OP_results(pred_op) != 0) {
01056 for (i = 0; i < OP_results(pred_op); i++) {
01057 EBO_TN_INFO *result_tninfo = opinfo->actual_rslt[i];
01058 if ((result_tninfo == NULL) ||
01059 (result_tninfo->reference_count != 0)) return FALSE;
01060 }
01061 }
01062
01063
01064 INT base_idx = TOP_Find_Operand_Use(OP_code(op),OU_base);
01065 EBO_TN_INFO *input_info = opinfo->actual_opnd[base_idx];
01066 if ((input_info == NULL) ||
01067 (input_info->in_op == NULL) ||
01068 (input_info->local_tn == NULL) ||
01069 (input_info->predicate_tninfo != new_predicate_tninfo) ||
01070 OP_Defs_TN(pred_op, input_info->local_tn)) {
01071
01072
01073 if (EBO_Trace_Data_Flow) {
01074 fprintf(TFile,"predicates not hoisted because address not hoisted\n");
01075 }
01076 return FALSE;
01077 }
01078 } else if (OP_effectively_copy(op)) {
01079 INT val_indx = EBO_Copy_Operand(op);
01080 if ((val_indx <= 0) ||
01081 !TNs_Are_Equivalent(OP_opnd(op,val_indx), OP_opnd(pred_op,val_indx))) {
01082
01083 if (EBO_Trace_Data_Flow) {
01084 fprintf(TFile,"copy operands are different\n");
01085 }
01086 return FALSE;
01087 }
01088 } else {
01089
01090 for (i = 0; i < OP_results(pred_op); i++) {
01091 if (opinfo->actual_rslt[i] == NULL) return FALSE;
01092 if (!EBO_tn_available (bb, opinfo->actual_rslt[i])) {
01093 if (EBO_Trace_Data_Flow) {
01094 fprintf(TFile,"previous result is not available\n");
01095 }
01096 return FALSE;
01097 }
01098 }
01099
01100
01101 for (i = OP_PREDICATE_OPND+1; i < OP_opnds(pred_op); i++) {
01102 EBO_TN_INFO *input_info = opinfo->actual_opnd[i];
01103 if ((input_info == NULL) ||
01104 (input_info->in_op == NULL) ||
01105 (input_info->local_tn == NULL) ||
01106 (input_info->predicate_tninfo != new_predicate_tninfo) ||
01107 OP_Defs_TN(pred_op, input_info->local_tn)) {
01108
01109
01110 if (EBO_Trace_Data_Flow) {
01111 fprintf(TFile,"predicates not hoisted because inputs not hoisted\n");
01112 }
01113 return FALSE;
01114 }
01115 }
01116 }
01117
01118 OPS ops = OPS_EMPTY;
01119 if (OP_store(op)) {
01120
01121 TN *value_tn = OP_opnd(op, val_idx);
01122 if (!TNs_Are_Equivalent(OP_opnd(op, val_idx),OP_opnd(pred_op, val_idx))) {
01123
01124
01125
01126
01127 if (has_assigned_reg(value_tn) || EBO_in_loop) {
01128 if (EBO_Trace_Data_Flow) {
01129 fprintf(TFile,"predicates not hoisted because inputs can not be merged\n");
01130 }
01131 return FALSE;
01132 }
01133
01134 OPS ops1 = OPS_EMPTY;
01135 value_tn = Dup_TN(value_tn);
01136
01137 EBO_Exp_COPY (predicate1_tn,
01138 value_tn,
01139 OP_opnd(pred_op, val_idx),
01140 &ops1);
01141 OP_srcpos(OPS_last(&ops1)) = OP_srcpos(pred_op);
01142 if (EBO_in_loop) EBO_Set_OP_omega (OPS_last(&ops1), predicate1_info, opinfo->actual_opnd[val_idx]);
01143 OPS_Append_Ops( &ops, &ops1);
01144
01145 OPS_Init(&ops1);
01146 EBO_Exp_COPY (predicate2_tn,
01147 value_tn,
01148 OP_opnd(op, val_idx),
01149 &ops1);
01150 OP_srcpos(OPS_last(&ops1)) = OP_srcpos(op);
01151 if (EBO_in_loop) EBO_Set_OP_omega (OPS_last(&ops1), predicate2_info, opnd_tninfo[val_idx]);
01152 OPS_Append_Ops( &ops, &ops1);
01153 }
01154
01155
01156 OP *new_op = Dup_OP(op);
01157 Set_OP_opnd (new_op, OP_PREDICATE_OPND, new_predicate_tn);
01158 Set_OP_opnd (new_op, val_idx, value_tn);
01159 if (OP_memory(op)) {
01160 Copy_WN_For_Memory_OP (new_op, op);
01161 }
01162 OP_srcpos(new_op) = OP_srcpos(op);
01163 if (EBO_in_loop) {
01164 EBO_Copy_OP_omega( new_op, op);
01165 EBO_Set_Predicate_omega ( new_op, new_predicate_tninfo);
01166 }
01167 OPS_Append_Op( &ops, new_op);
01168
01169 if (OP_results(op) != 0) {
01170 OPS ops1 = OPS_EMPTY;
01171 for (i = 0; i < OP_results(pred_op); i++) {
01172 EBO_Exp_COPY (predicate1_tn,
01173 OP_result(pred_op, i),
01174 OP_result(op, i),
01175 &ops1);
01176 OP_srcpos(OPS_last(&ops1)) = OP_srcpos(pred_op);
01177 if (EBO_in_loop) EBO_Set_OP_omega (OPS_last(&ops1), predicate1_info, NULL);
01178 }
01179 OPS_Append_Ops( &ops, &ops1);
01180 }
01181
01182
01183 remove_op (opinfo);
01184 OP_Change_To_Noop(opinfo->in_op);
01185 opinfo->in_op = NULL;
01186 opinfo->in_bb = NULL;
01187 } else {
01188
01189 Set_OP_opnd (pred_op, OP_PREDICATE_OPND, new_predicate_tn);
01190 opinfo->actual_opnd[OP_PREDICATE_OPND] = new_predicate_tninfo;
01191 for (i = 0; i < OP_results(pred_op); i++) {
01192 if (opinfo->actual_rslt[i] != NULL) {
01193 if (opinfo->actual_rslt[i]->predicate_tninfo != NULL) {
01194 dec_ref_count(opinfo->actual_rslt[i]->predicate_tninfo);
01195 }
01196 opinfo->actual_rslt[i]->predicate_tninfo = new_predicate_tninfo;
01197 if (new_predicate_tninfo != NULL) {
01198 inc_ref_count(new_predicate_tninfo);
01199 }
01200 }
01201 }
01202
01203 if (OP_effectively_copy(op)) {
01204
01205 if (EBO_Trace_Optimization) fprintf(TFile,"hoist predicate for complementary copy\n");
01206 return FALSE;
01207 }
01208
01209
01210 OPS ops1 = OPS_EMPTY;
01211 for (i = 0; i < OP_results(op); i++) {
01212 if (!TNs_Are_Equivalent(OP_result(op, i),OP_result(pred_op, i))) {
01213 EBO_Exp_COPY (predicate2_tn,
01214 OP_result(op, i),
01215 OP_result(pred_op, i),
01216 &ops1);
01217 OP_srcpos(OPS_last(&ops1)) = OP_srcpos(op);
01218 if (EBO_in_loop) EBO_Set_OP_omega (OPS_last(&ops1), predicate2_info, NULL);
01219 }
01220 }
01221 OPS_Append_Ops( &ops, &ops1);
01222 }
01223
01224 BB_Insert_Ops(bb, op, &ops, FALSE);
01225 if (EBO_Trace_Optimization) fprintf(TFile,"hoist predicate for complementary operations\n");
01226 return TRUE;
01227 }
01228
01229
01230
01231
01232 BOOL
01233 delete_subset_mem_op(OP *op,
01234 EBO_TN_INFO **opnd_tninfo,
01235 EBO_OP_INFO *opinfo,
01236 INT64 offset_pred,
01237 INT64 offset_succ)
01238 {
01239 OP *pred_op = opinfo->in_op;
01240 BB *bb = OP_bb(op);
01241 INT opcount = OP_opnds(op);
01242 TN *pred_result = OP_store(pred_op)
01243 ? OP_opnd(pred_op, TOP_Find_Operand_Use(OP_code(pred_op),OU_storeval))
01244 : OP_result(pred_op,0);
01245 TN *succ_result = OP_store(op)
01246 ? OP_opnd(op, TOP_Find_Operand_Use(OP_code(op),OU_storeval))
01247 : OP_result(op,0);
01248 INT size_pred;
01249 INT size_succ;
01250 BOOL succ_is_subset = FALSE;
01251 INT byte_offset;
01252 OPS ops = OPS_EMPTY;
01253
01254 if (EBO_Trace_Data_Flow) {
01255 fprintf(TFile,"%ssubset OP in BB:%d ",EBO_trace_pfx,BB_id(bb));
01256 Print_OP_No_SrcLine(op);
01257 fprintf(TFile," Matches OP in BB:%d ",BB_id(opinfo->in_bb));
01258 Print_OP_No_SrcLine(pred_op);
01259 }
01260
01261 if ((Opt_Level < 2) && (bb != opinfo->in_bb)) {
01262
01263 return FALSE;
01264 }
01265
01266 if (!EBO_in_peep &&
01267 (bb != opinfo->in_bb) &&
01268 !TN_Is_Constant(pred_result) &&
01269 has_assigned_reg(pred_result)) {
01270 if (EBO_Trace_Data_Flow) {
01271 #pragma mips_frequency_hint NEVER
01272 fprintf(TFile,"%sShouldn't move dedicated register references across blocks.\n",
01273 EBO_trace_pfx);
01274 }
01275 return FALSE;
01276 }
01277
01278 size_pred = CGTARG_Mem_Ref_Bytes(pred_op);
01279 size_succ = CGTARG_Mem_Ref_Bytes(op);
01280 if (size_pred < size_succ) return FALSE;
01281
01282 if ((offset_pred <= offset_succ) &&
01283 ((offset_pred + size_pred) >= (offset_succ + size_succ))) {
01284 succ_is_subset = TRUE;
01285 }
01286
01287 if (!succ_is_subset) {
01288 return FALSE;
01289 }
01290
01291
01292 if (CGTARG_Is_OP_Speculative(op) ||
01293 CGTARG_Is_OP_Speculative(pred_op) ||
01294 CGTARG_Is_OP_Check_Load(op) ||
01295 CGTARG_Is_OP_Check_Load(pred_op) ||
01296 BB_recovery(OP_bb(op)) ||
01297 BB_recovery(OP_bb(pred_op))) return FALSE;
01298
01299 byte_offset = offset_succ - offset_pred;
01300
01301 if (OP_load(op) && OP_load(pred_op) &&
01302 (OP_results(op) == 1) && (OP_results(pred_op) == 2) &&
01303 (2*size_succ == size_pred)) {
01304
01305 pred_result = (byte_offset >= size_succ) ? OP_result(pred_op,1) : OP_result(pred_op,0);
01306
01307 if (EBO_Trace_Optimization) {
01308 #pragma mips_frequency_hint NEVER
01309 fprintf(TFile,"%sRemove LoadPair - Load combination\n",EBO_trace_pfx);
01310 }
01311
01312 EBO_Exp_COPY((OP_has_predicate(op)?OP_opnd(op,OP_PREDICATE_OPND):NULL),
01313 succ_result, pred_result, &ops);
01314 if (EBO_in_loop) EBO_OPS_omega (&ops, (OP_has_predicate(op)?opnd_tninfo[OP_PREDICATE_OPND]:NULL));
01315 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
01316 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
01317 return TRUE;
01318 }
01319
01320 if (byte_offset > 8) return FALSE;
01321
01322 if (!OP_store(pred_op) || !OP_load(op)) {
01323
01324 return FALSE;
01325 }
01326
01327 if (TOP_Find_Operand_Use(OP_code(op), OU_postincr) >= 0) {
01328
01329 return FALSE;
01330 }
01331
01332 if ((TN_register_class(pred_result) != ISA_REGISTER_CLASS_integer) ||
01333 (TN_register_class(succ_result) != ISA_REGISTER_CLASS_integer)) {
01334
01335 return FALSE;
01336 }
01337
01338 TOP extr_op = TOP_extr_u;
01339 INT bit_size = size_succ*8;
01340 INT succ_offset = (offset_succ - offset_pred);
01341 INT bit_offset = (Target_Byte_Sex == BIG_ENDIAN ?
01342 size_pred-succ_offset-size_succ : succ_offset)*8;
01343
01344 Build_OP(extr_op, succ_result, OP_opnd(op,OP_PREDICATE_OPND), pred_result,
01345 Gen_Literal_TN(bit_offset, 4), Gen_Literal_TN(bit_size, 4), &ops);
01346 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops), opnd_tninfo[OP_PREDICATE_OPND],
01347 NULL, NULL, NULL);
01348 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
01349 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
01350
01351 if (EBO_Trace_Optimization) {
01352 fprintf(TFile,"%sReplace subset load with extract.\n",EBO_trace_pfx);
01353 }
01354
01355 return TRUE;
01356 }
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366 BOOL
01367 delete_reload_across_dependency (OP *op,
01368 EBO_TN_INFO **opnd_tninfo,
01369 EBO_OP_INFO *opinfo,
01370 EBO_OP_INFO *intervening_opinfo)
01371 {
01372 BB *bb = OP_bb(op);
01373 OPS ops = OPS_EMPTY;
01374 OP *pred_op = opinfo->in_op;
01375 OP *intervening_op = intervening_opinfo->in_op;
01376 TOP pred_opcode = OP_code(pred_op);
01377 TOP intervening_opcode = OP_code(intervening_op);
01378 INT pred_base_idx = TOP_Find_Operand_Use(pred_opcode, OU_base);
01379 INT intervening_base_idx = TOP_Find_Operand_Use(intervening_opcode, OU_base);
01380 INT pred_inc_idx = TOP_Find_Operand_Use(pred_opcode, OU_postincr);
01381 INT intervening_inc_idx = TOP_Find_Operand_Use(intervening_opcode, OU_postincr);
01382 INT size_pred;
01383 INT size_succ;
01384 INT size_intervening;
01385 TN *predicate_tn = OP_has_predicate(op)?OP_opnd(op,OP_PREDICATE_OPND):NULL;
01386
01387 TN *pred_result;
01388 TN *intervening_result;
01389 TN *pred_index;
01390 TN *intervening_index;
01391 TN *predicate1;
01392 TN *predicate2;
01393
01394
01395 if (EBO_in_loop) return FALSE;
01396 if (EBO_in_peep) return FALSE;
01397
01398 if (EBO_Trace_Execution) {
01399 #pragma mips_frequency_hint NEVER
01400 fprintf(TFile,"%sEnter delete_reload_across_dependency.\n",EBO_trace_pfx);
01401 Print_OP_No_SrcLine(pred_op);
01402 Print_OP_No_SrcLine(intervening_op);
01403 Print_OP_No_SrcLine(op);
01404 }
01405
01406
01407 if ((pred_op == NULL) ||
01408 (intervening_op == NULL) ||
01409 !OP_load(op) ||
01410 !(OP_load(pred_op) || OP_store(pred_op)) ||
01411 !OP_store(intervening_op)) return FALSE;
01412
01413 pred_op = opinfo->in_op;
01414 intervening_op = intervening_opinfo->in_op;
01415
01416 if (OP_prefetch(op) ||
01417 OP_prefetch(pred_op) ||
01418 OP_prefetch(intervening_op)) return FALSE;
01419
01420 if (OP_unalign_mem(op) ||
01421 OP_unalign_mem(pred_op) ||
01422 OP_unalign_mem(intervening_op)) return FALSE;
01423
01424 size_succ = CGTARG_Mem_Ref_Bytes(op);
01425 size_pred = CGTARG_Mem_Ref_Bytes(pred_op);
01426 size_intervening = CGTARG_Mem_Ref_Bytes(intervening_op);
01427
01428 if ((size_succ != size_pred) ||
01429 (size_succ != size_intervening)) return FALSE;
01430
01431 if (TOP_Find_Operand_Use(OP_code(op), OU_postincr) >= 0) {
01432
01433 if (EBO_Trace_Data_Flow) {
01434 #pragma mips_frequency_hint NEVER
01435 fprintf(TFile,"%sIncremented Load for intervening store combination\n",
01436 EBO_trace_pfx);
01437 }
01438 return FALSE;
01439 }
01440
01441
01442 if (OP_results(op) == 2) return FALSE;
01443 if ((OP_store(pred_op) &&
01444 ((OP_results(pred_op) > 1) ||
01445 ((OP_results(pred_op) > 0) &&
01446 (pred_inc_idx < 0)))) ||
01447 (OP_store(intervening_op) &&
01448 ((OP_results(intervening_op) > 1) ||
01449 ((OP_results(intervening_op) > 0) &&
01450 (intervening_inc_idx < 0))))) return FALSE;
01451 if ((OP_load(pred_op) &&
01452 ((OP_results(pred_op) > 2) ||
01453 ((OP_results(pred_op) > 1) &&
01454 (pred_inc_idx < 0)))) ||
01455 (OP_load(intervening_op) &&
01456 ((OP_results(intervening_op) > 2) ||
01457 ((OP_results(intervening_op) > 1) &&
01458 (intervening_inc_idx < 0))))) return FALSE;
01459
01460
01461 if (CGTARG_Is_OP_Speculative(op) ||
01462 CGTARG_Is_OP_Speculative(pred_op) ||
01463 CGTARG_Is_OP_Check_Load(op) ||
01464 CGTARG_Is_OP_Check_Load(pred_op) ||
01465 BB_recovery(OP_bb(op)) ||
01466 BB_recovery(OP_bb(pred_op))) return FALSE;
01467
01468
01469 pred_result = OP_store(pred_op) ? OP_opnd(pred_op,
01470 TOP_Find_Operand_Use(pred_opcode, OU_storeval))
01471 : OP_result(pred_op,0);
01472 intervening_result = OP_opnd(intervening_op,
01473 TOP_Find_Operand_Use(intervening_opcode, OU_storeval));
01474
01475 if ((TN_register_class(intervening_result) != TN_register_class(pred_result)) ||
01476 (TN_register_class(intervening_result) != TN_register_class(OP_result(op,0)))) {
01477 if (EBO_Trace_Data_Flow) {
01478 #pragma mips_frequency_hint NEVER
01479 fprintf(TFile,"%sInter-register copies are not supported\n",
01480 EBO_trace_pfx);
01481 }
01482 return FALSE;
01483 }
01484
01485 if (TNs_Are_Equivalent( pred_result, intervening_result)) {
01486
01487
01488
01489 if ((size_succ != 8) &&
01490 (TN_register_class(intervening_result) == ISA_REGISTER_CLASS_integer) &&
01491 (TN_register_class(pred_result) == ISA_REGISTER_CLASS_integer)) {
01492
01493
01494 TOP extr_op = TOP_extr_u;
01495 INT bit_size = size_succ*8;
01496 INT bit_offset = 0;
01497
01498 Build_OP(extr_op, OP_result(op, 0), predicate_tn, pred_result,
01499 Gen_Literal_TN(bit_offset, 4), Gen_Literal_TN(bit_size, 4), &ops);
01500 if (predicate_tn != True_TN) Set_OP_cond_def_kind(OPS_last(&ops), OP_PREDICATED_DEF);
01501 OP_srcpos(OPS_last(&ops)) = OP_srcpos(op);
01502 } else {
01503
01504 EBO_Exp_COPY(predicate_tn, OP_result(op, 0), pred_result, &ops);
01505 if (predicate_tn != True_TN) Set_OP_cond_def_kind(OPS_last(&ops), OP_PREDICATED_DEF);
01506 OP_srcpos(OPS_last(&ops)) = OP_srcpos(op);
01507 }
01508
01509 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
01510
01511 if (EBO_Trace_Optimization) {
01512 #pragma mips_frequency_hint NEVER
01513 fprintf(TFile,"%sReload across intervening store is not needed.\n",EBO_trace_pfx);
01514 Print_OP_No_SrcLine(pred_op);
01515 Print_OP_No_SrcLine(intervening_op);
01516 Print_OP_No_SrcLine(op);
01517 }
01518
01519 return TRUE;
01520 }
01521
01522
01523
01524
01525
01526 pred_index = OP_opnd(pred_op, pred_base_idx);
01527 intervening_index = OP_opnd(intervening_op, intervening_base_idx);
01528
01529 if ((pred_inc_idx >= 0) ||
01530 (intervening_inc_idx >= 0)) {
01531 if ((pred_inc_idx < 0) || (intervening_inc_idx < 0)) {
01532 if (EBO_Trace_Data_Flow) {
01533 #pragma mips_frequency_hint NEVER
01534 fprintf(TFile,"%sBase address not available for compare because of increment\n",
01535 EBO_trace_pfx);
01536 }
01537 return FALSE;
01538 }
01539 TN *pred_inc_tn = OP_opnd(pred_op,pred_inc_idx);
01540 TN *intervening_inc_tn = OP_opnd(intervening_op,intervening_inc_idx);
01541 if ((TN_Is_Constant(pred_inc_tn) ||
01542 TN_Is_Constant(intervening_inc_tn)) &&
01543 (pred_inc_tn != intervening_inc_tn)) {
01544 if (EBO_Trace_Data_Flow) {
01545 #pragma mips_frequency_hint NEVER
01546 fprintf(TFile,"%sBase address not available for compare because of different constant increment\n",
01547 EBO_trace_pfx);
01548 }
01549 return FALSE;
01550 }
01551 if (opinfo->actual_opnd[pred_inc_idx] != intervening_opinfo->actual_opnd[intervening_inc_idx]) {
01552 if (EBO_Trace_Data_Flow) {
01553 #pragma mips_frequency_hint NEVER
01554 fprintf(TFile,"%sBase address not available for compare because of different increment\n",
01555 EBO_trace_pfx);
01556 }
01557 return FALSE;
01558 }
01559 pred_index = OP_load(pred_op) ? OP_result(pred_op,1) : OP_result(pred_op,0);
01560 intervening_index = OP_load(intervening_op) ? OP_result(intervening_op,1) : OP_result(intervening_op,0);
01561 }
01562
01563
01564 if (!EBO_tn_available (bb, opinfo->actual_opnd[pred_base_idx]) ||
01565 !EBO_tn_available (bb, intervening_opinfo->actual_opnd[intervening_base_idx])) {
01566 if (EBO_Trace_Data_Flow) {
01567 #pragma mips_frequency_hint NEVER
01568 fprintf(TFile,"%sBase address not available for compare\n",
01569 EBO_trace_pfx);
01570 }
01571 return FALSE;
01572 }
01573
01574
01575
01576
01577
01578 predicate1 = Dup_TN_Even_If_Dedicated(predicate_tn);
01579 predicate2 = Dup_TN_Even_If_Dedicated(predicate_tn);
01580
01581
01582 Build_OP (TOP_cmp_eq_unc, predicate1, predicate2, predicate_tn, pred_index, intervening_index, &ops);
01583 OP_srcpos(OPS_last(&ops)) = OP_srcpos(op);
01584
01585 if ((size_succ != 8) &&
01586 (TN_register_class(intervening_result) == ISA_REGISTER_CLASS_integer) &&
01587 (TN_register_class(pred_result) == ISA_REGISTER_CLASS_integer)) {
01588
01589
01590 TOP extr_op = TOP_extr_u;
01591 INT bit_size = size_succ*8;
01592 INT bit_offset = 0;
01593
01594
01595 Build_OP(extr_op, OP_result(op, 0), predicate_tn, pred_result,
01596 Gen_Literal_TN(bit_offset, 4), Gen_Literal_TN(bit_size, 4), &ops);
01597 if (predicate_tn != True_TN) Set_OP_cond_def_kind(OPS_last(&ops), OP_PREDICATED_DEF);
01598 OP_srcpos(OPS_last(&ops)) = OP_srcpos(op);
01599
01600
01601 Build_OP(extr_op, OP_result(op, 0), predicate1, intervening_result,
01602 Gen_Literal_TN(bit_offset, 4), Gen_Literal_TN(bit_size, 4), &ops);
01603 Set_OP_cond_def_kind(OPS_last(&ops), OP_PREDICATED_DEF);
01604 OP_srcpos(OPS_last(&ops)) = OP_srcpos(op);
01605 } else {
01606
01607 OPS ops1 = OPS_EMPTY;
01608
01609
01610 EBO_Exp_COPY(predicate_tn, OP_result(op, 0), pred_result, &ops1);
01611 if (predicate_tn != True_TN) Set_OP_cond_def_kind(OPS_last(&ops1), OP_PREDICATED_DEF);
01612 OP_srcpos(OPS_last(&ops1)) = OP_srcpos(op);
01613 OPS_Append_Ops( &ops, &ops1);
01614
01615
01616 OPS_Init(&ops1);
01617 EBO_Exp_COPY(predicate1, OP_result(op, 0), intervening_result, &ops1);
01618 Set_OP_cond_def_kind(OPS_last(&ops1), OP_PREDICATED_DEF);
01619 OP_srcpos(OPS_last(&ops1)) = OP_srcpos(op);
01620 OPS_Append_Ops( &ops, &ops1);
01621 }
01622
01623 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
01624
01625 if (EBO_Trace_Optimization) {
01626 #pragma mips_frequency_hint NEVER
01627 fprintf(TFile,"%sRemove Reload across intervening store.\n",EBO_trace_pfx);
01628 }
01629
01630 return TRUE;
01631 }
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641 static
01642 BOOL
01643 delete_memory_op (OP *op,
01644 EBO_TN_INFO **opnd_tninfo,
01645 EBO_OP_INFO *opinfo)
01646 {
01647 OPS ops = OPS_EMPTY;
01648 INT size_pred;
01649 INT size_succ;
01650 TN *predicate_tn = OP_has_predicate(op)?OP_opnd(op,OP_PREDICATE_OPND):NULL;
01651
01652 if (OP_prefetch(op)) {
01653
01654
01655
01656
01657
01658 if (EBO_Trace_Optimization) {
01659 fprintf(TFile,"%sRemove following Prefetch combination\n",EBO_trace_pfx);
01660 }
01661 return TRUE;
01662 }
01663
01664 if (OP_prefetch(opinfo->in_op)) {
01665
01666
01667
01668
01669 return FALSE;
01670 }
01671
01672 if (OP_unalign_mem(op) || OP_unalign_mem(opinfo->in_op)) return FALSE;
01673
01674 size_pred = CGTARG_Mem_Ref_Bytes(opinfo->in_op);
01675 size_succ = CGTARG_Mem_Ref_Bytes(op);
01676
01677
01678
01679
01680
01681
01682 if (CGTARG_Is_OP_Speculative(op) ||
01683 CGTARG_Is_OP_Speculative(opinfo->in_op) ||
01684 CGTARG_Is_OP_Check_Load(op) ||
01685 CGTARG_Is_OP_Check_Load(opinfo->in_op) ||
01686 BB_recovery(OP_bb(op)) ||
01687 BB_recovery(OP_bb(opinfo->in_op))) return FALSE;
01688
01689
01690
01691
01692 if (CGTARG_Load_with_UNAT (op) || CGTARG_Store_With_UNAT (op)) {
01693 return FALSE;
01694 }
01695
01696 if (OP_load(op) && OP_load(opinfo->in_op)) {
01697 if (TOP_Find_Operand_Use(OP_code(op), OU_postincr) >= 0) {
01698
01699 if (EBO_Trace_Data_Flow) {
01700 #pragma mips_frequency_hint NEVER
01701 fprintf(TFile,"%sIncremented Load for Load - Load combination\n",
01702 EBO_trace_pfx);
01703 }
01704 return FALSE;
01705 }
01706 if ((TN_register_class(OP_result(op,0)) !=
01707 TN_register_class(OP_result(opinfo->in_op, 0))) ||
01708 (TN_is_fpu_int(OP_result(op,0)) !=
01709 TN_is_fpu_int(OP_result(opinfo->in_op, 0)))) {
01710 if (EBO_Trace_Data_Flow) {
01711 #pragma mips_frequency_hint NEVER
01712 fprintf(TFile,"%sType mismatch for Load - Load combination\n",
01713 EBO_trace_pfx);
01714 }
01715
01716 return FALSE;
01717 }
01718 if ((size_pred != size_succ) ||
01719 (OP_results(op) != OP_results(opinfo->in_op)) ||
01720 (TN_size(OP_result(opinfo->in_op, 0)) != TN_size(OP_result(op, 0)))) {
01721
01722
01723
01724
01725
01726 if (EBO_Trace_Data_Flow) {
01727 #pragma mips_frequency_hint NEVER
01728 fprintf(TFile,"%sSize mismatch for Load - Load combination: %d:%d %d:%d \n",
01729 EBO_trace_pfx,size_pred,size_succ,
01730 TN_size(OP_result(opinfo->in_op, 0)),TN_size(OP_result(op, 0)));
01731 }
01732
01733 return delete_subset_mem_op (op, opnd_tninfo, opinfo, 0, 0);
01734 }
01735 if (!EBO_in_peep &&
01736 (OP_bb(op) != OP_bb(opinfo->in_op)) &&
01737 !TN_Is_Constant(OP_result(opinfo->in_op, 0)) &&
01738 has_assigned_reg(OP_result(opinfo->in_op, 0))) {
01739 if (EBO_Trace_Data_Flow) {
01740 #pragma mips_frequency_hint NEVER
01741 fprintf(TFile,"%sShouldn't move dedicated register references across blocks.\n",
01742 EBO_trace_pfx);
01743 }
01744 return FALSE;
01745 }
01746 if (EBO_Trace_Optimization) {
01747 #pragma mips_frequency_hint NEVER
01748 fprintf(TFile,"%sRemove Load - Load combination\n",EBO_trace_pfx);
01749 }
01750
01751 EBO_Exp_COPY(predicate_tn, OP_result(op, 0), OP_result(opinfo->in_op, 0), &ops);
01752 if (OP_results(op) == 2) {
01753 EBO_Exp_COPY(predicate_tn, OP_result(op, 1), OP_result(opinfo->in_op, 1), &ops);
01754 }
01755 if (EBO_in_loop) EBO_OPS_omega (&ops, (OP_has_predicate(op)?opnd_tninfo[OP_PREDICATE_OPND]:NULL));
01756 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
01757 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
01758 return TRUE;
01759 } else if (OP_load(op) && OP_store(opinfo->in_op)) {
01760
01761
01762
01763 INT storeval_idx = TOP_Find_Operand_Use(OP_code(opinfo->in_op),OU_storeval);
01764 TN *storeval_tn = OP_opnd(opinfo->in_op, storeval_idx);
01765 if (TOP_Find_Operand_Use(OP_code(op), OU_postincr) >= 0) {
01766
01767 if (EBO_Trace_Data_Flow) {
01768 #pragma mips_frequency_hint NEVER
01769 fprintf(TFile,"%sIncremented Load for Load - Store combination\n",
01770 EBO_trace_pfx);
01771 }
01772 return FALSE;
01773 }
01774 if ((TN_register_class(OP_result(op,0)) !=
01775 TN_register_class(storeval_tn)) ||
01776 (TN_is_fpu_int(OP_result(op,0)) !=
01777 TN_is_fpu_int(storeval_tn))) {
01778 if (EBO_Trace_Data_Flow) {
01779 #pragma mips_frequency_hint NEVER
01780 fprintf(TFile,"%sType mismatch for Store - Load combination\n",
01781 EBO_trace_pfx);
01782 }
01783 return FALSE;
01784 }
01785 if (!EBO_in_peep &&
01786 (OP_bb(op) != OP_bb(opinfo->in_op)) &&
01787 !TN_Is_Constant(storeval_tn) &&
01788 has_assigned_reg(storeval_tn)) {
01789 if (EBO_Trace_Data_Flow) {
01790 #pragma mips_frequency_hint NEVER
01791 fprintf(TFile,"%sShouldn't move dedicated register references across blocks.\n",
01792 EBO_trace_pfx);
01793 }
01794 return FALSE;
01795 }
01796
01797 if (size_pred == size_succ) {
01798
01799 if (TN_size(storeval_tn) > size_succ) {
01800
01801
01802
01803
01804
01805 if (EBO_Trace_Data_Flow) {
01806 #pragma mips_frequency_hint NEVER
01807 fprintf(TFile,"%sSize mismatch for Store - Load combination: %d %d %d\n",
01808 EBO_trace_pfx,size_pred,TN_size(storeval_tn),size_succ);
01809 }
01810
01811 return delete_subset_mem_op (op, opnd_tninfo, opinfo, 0, 0);
01812 }
01813 if (EBO_Trace_Optimization) {
01814 #pragma mips_frequency_hint NEVER
01815 fprintf(TFile,"%sRemove Store - Load combination\n",EBO_trace_pfx);
01816 }
01817
01818 EBO_Exp_COPY(predicate_tn, OP_result(op, 0), storeval_tn, &ops);
01819 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops),
01820 (OP_has_predicate(op)?opnd_tninfo[OP_PREDICATE_OPND]:NULL),
01821 opinfo->actual_opnd[storeval_idx]);
01822 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
01823 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
01824 return TRUE;
01825 } else {
01826
01827
01828
01829 return delete_subset_mem_op (op, opnd_tninfo, opinfo, 0, 0);
01830 }
01831 } else if (OP_store(op) && OP_store(opinfo->in_op) &&
01832 (OP_bb(op) == OP_bb(opinfo->in_op))) {
01833
01834
01835
01836 if (size_pred != size_succ) return FALSE;
01837 if (opinfo->op_must_not_be_removed) return FALSE;
01838 if (TOP_Find_Operand_Use(OP_code(opinfo->in_op), OU_postincr) >= 0) {
01839
01840 if (EBO_Trace_Data_Flow) {
01841 #pragma mips_frequency_hint NEVER
01842 fprintf(TFile,"%sIncremented Store for Store - Store combination\n",
01843 EBO_trace_pfx);
01844 }
01845 return FALSE;
01846 }
01847 if (EBO_Trace_Optimization) {
01848 fprintf(TFile,"%sRemove Store - Store combination\n",EBO_trace_pfx);
01849 }
01850 remove_op (opinfo);
01851 OP_Change_To_Noop(opinfo->in_op);
01852 opinfo->in_op = NULL;
01853 opinfo->in_bb = NULL;
01854 return FALSE;
01855 } else if (OP_load(opinfo->in_op) && OP_store(op)) {
01856
01857
01858
01859 INT storeval_idx = TOP_Find_Operand_Use(OP_code(op),OU_storeval);
01860 TN *storeval_tn = OP_opnd(op, storeval_idx);
01861
01862 if (TOP_Find_Operand_Use(OP_code(op), OU_postincr) >= 0) {
01863
01864 if (EBO_Trace_Data_Flow) {
01865 #pragma mips_frequency_hint NEVER
01866 fprintf(TFile,"%sIncremented Store for Load - Store combination\n",
01867 EBO_trace_pfx);
01868 }
01869 return FALSE;
01870 }
01871 if ((TN_register_class(OP_result(opinfo->in_op,0)) !=
01872 TN_register_class(storeval_tn)) ||
01873 (TN_is_fpu_int(OP_result(opinfo->in_op,0)) !=
01874 TN_is_fpu_int(storeval_tn))) {
01875 if (EBO_Trace_Data_Flow) {
01876 #pragma mips_frequency_hint NEVER
01877 fprintf(TFile,"%sType mismatch for Load - Store combination\n",
01878 EBO_trace_pfx);
01879 }
01880 return FALSE;
01881 }
01882 if (!EBO_in_peep &&
01883 (OP_bb(op) != OP_bb(opinfo->in_op)) &&
01884 !TN_Is_Constant(storeval_tn) &&
01885 has_assigned_reg(storeval_tn)) {
01886 if (EBO_Trace_Data_Flow) {
01887 #pragma mips_frequency_hint NEVER
01888 fprintf(TFile,"%sShouldn't move dedicated register references across blocks.\n",
01889 EBO_trace_pfx);
01890 }
01891 return FALSE;
01892 }
01893
01894 if ((size_pred != size_succ) ||
01895 (TN_size(storeval_tn) != size_succ)) {
01896
01897 if (EBO_Trace_Data_Flow) {
01898 #pragma mips_frequency_hint NEVER
01899 fprintf(TFile,"%sSize mismatch for Load - Store combination: %d %d %d\n",
01900 EBO_trace_pfx,size_pred,TN_size(storeval_tn),size_succ);
01901 }
01902
01903 return FALSE;
01904 }
01905
01906 if ((opnd_tninfo[storeval_idx] != NULL) &&
01907 (opnd_tninfo[storeval_idx]->in_op != NULL) &&
01908 (opinfo->in_op != NULL) &&
01909 (opnd_tninfo[storeval_idx]->in_op == opinfo->in_op)) {
01910
01911
01912 if (EBO_Trace_Optimization) {
01913 #pragma mips_frequency_hint NEVER
01914 fprintf(TFile,"%sRemove Load - Store combination\n",EBO_trace_pfx);
01915 }
01916
01917 return TRUE;
01918 }
01919 }
01920
01921 return FALSE;
01922 }
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932 BOOL
01933 delete_duplicate_op (OP *op,
01934 EBO_TN_INFO **opnd_tninfo,
01935 EBO_OP_INFO *opinfo)
01936 {
01937 INT resnum;
01938 OPS ops = OPS_EMPTY;
01939
01940 if (EBO_Trace_Data_Flow) {
01941 fprintf(TFile,"%sDuplicate OP in BB:%d ",EBO_trace_pfx,BB_id(OP_bb(op)));
01942 Print_OP_No_SrcLine(op);
01943 fprintf(TFile," Matches OP in BB:%d ",BB_id(opinfo->in_bb));
01944 Print_OP_No_SrcLine(opinfo->in_op);
01945 }
01946
01947 if ((Opt_Level < 2) && (OP_bb(op) != opinfo->in_bb)) {
01948
01949 return FALSE;
01950 }
01951
01952 if (OP_has_predicate(op) &&
01953 (OP_opnd(op,OP_PREDICATE_OPND) != OP_opnd(opinfo->in_op,OP_PREDICATE_OPND))) {
01954 OP *pred_op = opinfo->in_op;
01955 TN *predicate1_tn = OP_opnd(pred_op,OP_PREDICATE_OPND);
01956 TN *predicate2_tn = OP_opnd(op,OP_PREDICATE_OPND);
01957 EBO_TN_INFO *predicate1_info = opinfo->actual_opnd[OP_PREDICATE_OPND];
01958 EBO_TN_INFO *predicate2_info = opnd_tninfo[OP_PREDICATE_OPND];
01959
01960 if ((OP_code(op) == OP_code(pred_op)) &&
01961 EBO_predicate_complements(predicate1_tn, predicate1_info,
01962 predicate2_tn, predicate2_info)) {
01963 return hoist_predicate_of_duplicate_complement (op, opnd_tninfo, opinfo);
01964 }
01965 if (OP_store(pred_op) && OP_store(op)) {
01966 if (!EBO_predicate_dominates(predicate2_tn, predicate2_info,
01967 predicate1_tn, predicate1_info)) {
01968 if (EBO_Trace_Data_Flow) {
01969 fprintf(TFile,"%sStores can not be combined because predicates do not match\n",EBO_trace_pfx);
01970 }
01971 return FALSE;
01972 }
01973 } else {
01974 if (!EBO_predicate_dominates(predicate1_tn, predicate1_info,
01975 predicate2_tn, predicate2_info)) {
01976 if (EBO_Trace_Data_Flow) {
01977 fprintf(TFile,"%sExpressions can not be combined because predicates do not match\n",EBO_trace_pfx);
01978 }
01979 return FALSE;
01980 }
01981 }
01982 }
01983
01984 if (OP_memory(op)) {
01985
01986 return delete_memory_op (op, opnd_tninfo, opinfo);
01987 } else if ((OP_results(op) == 2) &&
01988 ((OP_result(op,0) != NULL) &&
01989 ((OP_result(op,0) == True_TN) ||
01990 (TN_register_class(OP_result(op,0)) == ISA_REGISTER_CLASS_predicate)))) {
01991
01992 return condition_redundant (op, opnd_tninfo, opinfo);
01993 } else {
01994
01995 if (OP_has_predicate(op) &&
01996 (OP_opnd(op,OP_PREDICATE_OPND) != True_TN)) {
01997
01998
01999 for (resnum = 0; resnum < OP_results(op); resnum++) {
02000 if (TN_register_class(OP_result(op, resnum)) == ISA_REGISTER_CLASS_predicate) {
02001 if (EBO_Trace_Data_Flow) {
02002 fprintf(TFile,"%sStores can not be combined because predicate copies can not be predicated\n",
02003 EBO_trace_pfx);
02004 }
02005 return FALSE;
02006 }
02007 }
02008 }
02009
02010
02011
02012 for (resnum = 0; resnum < OP_results(op); resnum++) {
02013 TN *rslt = OP_result(op, resnum);
02014 if (TN_register_class(rslt) == ISA_REGISTER_CLASS_predicate) {
02015 Build_OP (TOP_cmp_eq_unc, rslt, True_TN, OP_result(opinfo->in_op, resnum), Zero_TN, Zero_TN, &ops);
02016 } else {
02017 EBO_Exp_COPY((OP_has_predicate(op)?OP_opnd(op,OP_PREDICATE_OPND):NULL),
02018 rslt, OP_result(opinfo->in_op, resnum), &ops);
02019 }
02020 OP_srcpos(OPS_last(&ops)) = OP_srcpos(op);
02021 }
02022
02023 if (EBO_in_loop) EBO_OPS_omega (&ops, OP_has_predicate(op)?opnd_tninfo[OP_PREDICATE_OPND]:NULL);
02024 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
02025 return TRUE;
02026 }
02027 return FALSE;
02028 }
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038 static TOP Immediate_Compare(TOP opcode)
02039 {
02040 switch (opcode) {
02041 case TOP_cmp_eq: return TOP_cmp_i_eq;
02042 case TOP_cmp_eq_unc: return TOP_cmp_i_eq_unc;
02043 case TOP_cmp_ne: return TOP_cmp_i_ne;
02044 case TOP_cmp_ne_unc: return TOP_cmp_i_ne_unc;
02045 case TOP_cmp_ge: return TOP_cmp_i_ge;
02046 case TOP_cmp_ge_unc: return TOP_cmp_i_ge_unc;
02047 case TOP_cmp_geu: return TOP_cmp_i_geu;
02048 case TOP_cmp_geu_unc: return TOP_cmp_i_geu_unc;
02049 case TOP_cmp_lt: return TOP_cmp_i_lt;
02050 case TOP_cmp_lt_unc: return TOP_cmp_i_lt_unc;
02051 case TOP_cmp_ltu: return TOP_cmp_i_ltu;
02052 case TOP_cmp_ltu_unc: return TOP_cmp_i_ltu_unc;
02053 case TOP_cmp_gt: return TOP_cmp_i_gt;
02054 case TOP_cmp_gt_unc: return TOP_cmp_i_gt_unc;
02055 case TOP_cmp_gtu: return TOP_cmp_i_gtu;
02056 case TOP_cmp_gtu_unc: return TOP_cmp_i_gtu_unc;
02057 case TOP_cmp_le: return TOP_cmp_i_le;
02058 case TOP_cmp_le_unc: return TOP_cmp_i_le_unc;
02059 case TOP_cmp_leu: return TOP_cmp_i_leu;
02060 case TOP_cmp_leu_unc: return TOP_cmp_i_leu_unc;
02061 case TOP_cmp4_eq: return TOP_cmp4_i_eq;
02062 case TOP_cmp4_eq_unc: return TOP_cmp4_i_eq_unc;
02063 case TOP_cmp4_ne: return TOP_cmp4_i_ne;
02064 case TOP_cmp4_ne_unc: return TOP_cmp4_i_ne_unc;
02065 case TOP_cmp4_ge: return TOP_cmp4_i_ge;
02066 case TOP_cmp4_ge_unc: return TOP_cmp4_i_ge_unc;
02067 case TOP_cmp4_geu: return TOP_cmp4_i_geu;
02068 case TOP_cmp4_geu_unc: return TOP_cmp4_i_geu_unc;
02069 case TOP_cmp4_lt: return TOP_cmp4_i_lt;
02070 case TOP_cmp4_lt_unc: return TOP_cmp4_i_lt_unc;
02071 case TOP_cmp4_ltu: return TOP_cmp4_i_ltu;
02072 case TOP_cmp4_ltu_unc: return TOP_cmp4_i_ltu_unc;
02073 case TOP_cmp4_gt: return TOP_cmp4_i_gt;
02074 case TOP_cmp4_gt_unc: return TOP_cmp4_i_gt_unc;
02075 case TOP_cmp4_gtu: return TOP_cmp4_i_gtu;
02076 case TOP_cmp4_gtu_unc: return TOP_cmp4_i_gtu_unc;
02077 case TOP_cmp4_le: return TOP_cmp4_i_le;
02078 case TOP_cmp4_le_unc: return TOP_cmp4_i_le_unc;
02079 case TOP_cmp4_leu: return TOP_cmp4_i_leu;
02080 case TOP_cmp4_leu_unc: return TOP_cmp4_i_leu_unc;
02081 }
02082 return TOP_UNDEFINED;
02083 }
02084
02085
02086
02087
02088
02089
02090
02091
02092 static TOP Reverse_Compare(TOP opcode)
02093 {
02094 switch (opcode) {
02095 case TOP_cmp_eq:
02096 case TOP_cmp_eq_unc:
02097 case TOP_cmp_ne:
02098 case TOP_cmp_ne_unc:
02099 case TOP_cmp4_eq:
02100 case TOP_cmp4_eq_unc:
02101 case TOP_cmp4_ne:
02102 case TOP_cmp4_ne_unc:
02103 return opcode;
02104 case TOP_cmp_ge: return TOP_cmp_le;
02105 case TOP_cmp_ge_unc: return TOP_cmp_le_unc;
02106 case TOP_cmp_geu: return TOP_cmp_leu;
02107 case TOP_cmp_geu_unc: return TOP_cmp_leu_unc;
02108 case TOP_cmp_lt: return TOP_cmp_gt;
02109 case TOP_cmp_lt_unc: return TOP_cmp_gt_unc;
02110 case TOP_cmp_ltu: return TOP_cmp_gtu;
02111 case TOP_cmp_ltu_unc: return TOP_cmp_gtu_unc;
02112 case TOP_cmp_gt: return TOP_cmp_lt;
02113 case TOP_cmp_gt_unc: return TOP_cmp_lt_unc;
02114 case TOP_cmp_gtu: return TOP_cmp_ltu;
02115 case TOP_cmp_gtu_unc: return TOP_cmp_ltu_unc;
02116 case TOP_cmp_le: return TOP_cmp_ge;
02117 case TOP_cmp_le_unc: return TOP_cmp_ge_unc;
02118 case TOP_cmp_leu: return TOP_cmp_geu;
02119 case TOP_cmp_leu_unc: return TOP_cmp_geu_unc;
02120 case TOP_cmp4_ge: return TOP_cmp4_le;
02121 case TOP_cmp4_ge_unc: return TOP_cmp4_le_unc;
02122 case TOP_cmp4_geu: return TOP_cmp4_leu;
02123 case TOP_cmp4_geu_unc: return TOP_cmp4_leu_unc;
02124 case TOP_cmp4_lt: return TOP_cmp4_gt;
02125 case TOP_cmp4_lt_unc: return TOP_cmp4_gt_unc;
02126 case TOP_cmp4_ltu: return TOP_cmp4_gtu;
02127 case TOP_cmp4_ltu_unc: return TOP_cmp4_gtu_unc;
02128 case TOP_cmp4_gt: return TOP_cmp4_lt;
02129 case TOP_cmp4_gt_unc: return TOP_cmp4_lt_unc;
02130 case TOP_cmp4_gtu: return TOP_cmp4_ltu;
02131 case TOP_cmp4_gtu_unc: return TOP_cmp4_ltu_unc;
02132 case TOP_cmp4_le: return TOP_cmp4_ge;
02133 case TOP_cmp4_le_unc: return TOP_cmp4_ge_unc;
02134 case TOP_cmp4_leu: return TOP_cmp4_geu;
02135 case TOP_cmp4_leu_unc: return TOP_cmp4_geu_unc;
02136 }
02137 return TOP_UNDEFINED;
02138 }
02139
02140
02141
02142
02143
02144
02145
02146 static INT64 Normalize_Immediate(TOP opcode, INT64 immed)
02147 {
02148 switch (opcode) {
02149 case TOP_cmp4_i_eq:
02150 case TOP_cmp4_i_eq_unc:
02151 case TOP_cmp4_i_eq_and:
02152 case TOP_cmp4_i_eq_or:
02153 case TOP_cmp4_i_eq_or_andcm:
02154 case TOP_cmp4_i_ne_and:
02155 case TOP_cmp4_i_ne_or:
02156 case TOP_cmp4_i_ne_or_andcm:
02157 case TOP_cmp4_i_lt:
02158 case TOP_cmp4_i_lt_unc:
02159 case TOP_cmp4_i_eq_orcm:
02160 case TOP_cmp4_i_eq_andcm:
02161 case TOP_cmp4_i_eq_and_orcm:
02162 case TOP_cmp4_i_ne:
02163 case TOP_cmp4_i_ne_unc:
02164 case TOP_cmp4_i_ne_orcm:
02165 case TOP_cmp4_i_ne_andcm:
02166 case TOP_cmp4_i_ne_and_orcm:
02167 case TOP_cmp4_i_le:
02168 case TOP_cmp4_i_le_unc:
02169 case TOP_cmp4_i_gt:
02170 case TOP_cmp4_i_gt_unc:
02171 case TOP_cmp4_i_ge:
02172 case TOP_cmp4_i_ge_unc:
02173
02174
02175
02176 return SEXT_32(immed);
02177 case TOP_cmp4_i_ltu:
02178 case TOP_cmp4_i_ltu_unc:
02179 case TOP_cmp4_i_leu:
02180 case TOP_cmp4_i_leu_unc:
02181 case TOP_cmp4_i_gtu:
02182 case TOP_cmp4_i_gtu_unc:
02183 case TOP_cmp4_i_geu:
02184 case TOP_cmp4_i_geu_unc:
02185
02186
02187
02188 return TRUNC_32(immed);
02189 }
02190 return immed;
02191 }
02192
02193
02194
02195
02196
02197
02198 BOOL
02199 Constant_Operand0 (OP *op,
02200 TN **opnd_tn,
02201 EBO_TN_INFO **opnd_tninfo)
02202 {
02203 BB *bb = OP_bb(op);
02204 INT opndnum = OP_opnds(op);
02205 EBO_TN_INFO *tninfo;
02206
02207 TOP opcode = OP_code(op);
02208 TN *tnr = OP_result(op,0);
02209 INT l0_opnd1_idx;
02210 INT l0_opnd2_idx;
02211 TN *tn0;
02212 TN *tn1;
02213 INT64 const_val;
02214
02215 OP *pred_op;
02216 TOP pred_opcode;
02217 EBO_OP_INFO *pred_opinfo;
02218
02219 if (EBO_Trace_Execution) {
02220 #pragma mips_frequency_hint NEVER
02221 INT i;
02222 fprintf(TFile, "%sin BB:%d special0 OP :- %s",
02223 EBO_trace_pfx, BB_id(OP_bb(op)),TOP_Name(OP_code(op)));
02224 for (i = 0; i < opndnum; i++) {
02225 fprintf(TFile," ");
02226 Print_TN(opnd_tn[i],FALSE);
02227 }
02228 fprintf(TFile,"\n");
02229 }
02230
02231 if (!OP_has_predicate(op)) return FALSE;
02232 if (OP_opnds(op) < 1) return FALSE;
02233
02234 if (TN_register_class(tnr) == ISA_REGISTER_CLASS_float) {
02235 if (OP_opnds(op) < 4) return FALSE;
02236 l0_opnd1_idx = 2;
02237 l0_opnd2_idx = 3;
02238 tn0 = opnd_tn[l0_opnd1_idx];
02239 tn1 = opnd_tn[l0_opnd2_idx];
02240
02241 if (tn0 == FZero_TN) {
02242 if ((IEEE_Arithmetic >= IEEE_INEXACT) &&
02243 ((opcode == TOP_fmpy) ||
02244 (opcode == TOP_fmpy_s) ||
02245 (opcode == TOP_fmpy_d))) {
02246 OPS ops = OPS_EMPTY;
02247 if (EBO_Trace_Optimization) fprintf(TFile,"replace fmpy of 0.0 with 0.0\n");
02248 EBO_Exp_COPY((OP_has_predicate(op)?OP_opnd(op,OP_PREDICATE_OPND):NULL),
02249 tnr, FZero_TN, &ops);
02250 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops),
02251 OP_has_predicate(op)?opnd_tninfo[OP_PREDICATE_OPND]:NULL,
02252 NULL);
02253 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
02254 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
02255 return TRUE;
02256 }
02257 if ((opcode == TOP_fadd) ||
02258 (opcode == TOP_fadd_s) ||
02259 (opcode == TOP_fadd_d)) {
02260 OPS ops = OPS_EMPTY;
02261 if (EBO_Trace_Optimization) fprintf(TFile,"replace fadd of 0.0 with tn1\n");
02262 EBO_Exp_COPY((OP_has_predicate(op)?OP_opnd(op,OP_PREDICATE_OPND):NULL),
02263 tnr, tn1, &ops);
02264 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops),
02265 OP_has_predicate(op)?opnd_tninfo[OP_PREDICATE_OPND]:NULL,
02266 opnd_tninfo[l0_opnd2_idx]);
02267 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
02268 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
02269 return TRUE;
02270 }
02271 }
02272 if (tn0 == FOne_TN) {
02273 if ((opcode == TOP_fmpy) ||
02274 (opcode == TOP_fmpy_s) ||
02275 (opcode == TOP_fmpy_d)) {
02276 OPS ops = OPS_EMPTY;
02277 if (EBO_Trace_Optimization) fprintf(TFile,"replace fmpy of 1.0 with tn1\n");
02278 EBO_Exp_COPY((OP_has_predicate(op)?OP_opnd(op,OP_PREDICATE_OPND):NULL),
02279 tnr, tn1, &ops);
02280 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops),
02281 OP_has_predicate(op)?opnd_tninfo[OP_PREDICATE_OPND]:NULL,
02282 opnd_tninfo[l0_opnd2_idx]);
02283 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
02284 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
02285 return TRUE;
02286 }
02287 }
02288 }
02289
02290 if ((TN_register_class(tnr) != ISA_REGISTER_CLASS_integer) &&
02291 (TN_register_class(tnr) != ISA_REGISTER_CLASS_predicate)) {
02292
02293 return FALSE;
02294 }
02295
02296 l0_opnd1_idx = 1;
02297 l0_opnd2_idx = (OP_opnds(op) > 1) ? 2 : -1;
02298 tn0 = opnd_tn[l0_opnd1_idx];
02299 tn1 = (l0_opnd2_idx >= 0) ? opnd_tn[l0_opnd2_idx] : NULL;
02300 const_val = TN_Value(tn0);
02301
02302 if (TN_is_symbol(tn0)) {
02303
02304 return FALSE;
02305 }
02306
02307 if (TN_Is_Constant(tn1)) {
02308
02309 return FALSE;
02310 }
02311
02312 if (((TN_register_class(tn1) != ISA_REGISTER_CLASS_integer) &&
02313 (TN_register_class(tn1) != ISA_REGISTER_CLASS_predicate)) ||
02314 (TN_is_fpu_int(tnr) != TN_is_fpu_int(tn1))) {
02315
02316 if (EBO_Trace_Data_Flow) {
02317 fprintf(TFile,"%sType mismatch between result and operand\n",EBO_trace_pfx);
02318 }
02319 return FALSE;
02320 }
02321
02322 if ((const_val == 0) &&
02323 ((opcode == TOP_shl) ||
02324 (opcode == TOP_shl_i) ||
02325 (opcode == TOP_shr_u) ||
02326 (opcode == TOP_shr_i) ||
02327 (opcode == TOP_shr_i_u)||
02328 (opcode == TOP_shrp) ||
02329 (opcode == TOP_and) ||
02330 (opcode == TOP_and_i))) {
02331 OPS ops = OPS_EMPTY;
02332 if (EBO_Trace_Optimization) fprintf(TFile,"shift of zero\n");
02333 EBO_Exp_COPY((OP_has_predicate(op)?OP_opnd(op,OP_PREDICATE_OPND):NULL),
02334 tnr, Zero_TN, &ops);
02335 if (EBO_in_loop) EBO_OPS_omega (&ops, OP_has_predicate(op)?opnd_tninfo[OP_PREDICATE_OPND]:NULL);
02336 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
02337 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
02338 return TRUE;
02339 }
02340
02341 if ((opcode == TOP_add) &&
02342 (!TN_Is_Constant(tn1)) &&
02343 (ISA_LC_Value_In_Class ( const_val, LC_i14))) {
02344 OP *new_op;
02345 new_op = Mk_OP(TOP_adds, tnr, OP_opnd(op,OP_PREDICATE_OPND),
02346 Gen_Literal_TN(const_val, TN_size(tn1)), tn1);
02347 OP_srcpos(new_op) = OP_srcpos(op);
02348 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND], NULL, opnd_tninfo[l0_opnd2_idx] );
02349 BB_Insert_Op_After(OP_bb(op), op, new_op);
02350 if (EBO_Trace_Optimization) fprintf(TFile,"Replace add with adds\n");
02351 return TRUE;
02352 }
02353
02354
02355
02356
02357
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370 if ((opcode == TOP_addl) &&
02371 (!TN_Is_Constant(tn1)) &&
02372 (ISA_LC_Value_In_Class ( const_val, LC_i14))) {
02373 OP *new_op;
02374 TOP new_opcode = TOP_adds;
02375 new_op = Mk_OP(new_opcode, tnr, OP_opnd(op,OP_PREDICATE_OPND),
02376 Gen_Literal_TN(const_val, TN_size(tn1)), tn1);
02377 OP_srcpos(new_op) = OP_srcpos(op);
02378 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND], NULL, opnd_tninfo[l0_opnd2_idx] );
02379 BB_Insert_Op_After(OP_bb(op), op, new_op);
02380 if (EBO_Trace_Optimization) fprintf(TFile,"Replace addl with adds\n");
02381 return TRUE;
02382 }
02383
02384 if ((opcode == TOP_sub) &&
02385 (!TN_Is_Constant(tn1)) &&
02386 (ISA_LC_Value_In_Class ( const_val, LC_i8))) {
02387 OP *new_op;
02388 TOP new_opcode = TOP_sub_i;
02389 new_op = Mk_OP(new_opcode, tnr, OP_opnd(op,OP_PREDICATE_OPND),
02390 Gen_Literal_TN(const_val, TN_size(tn1)), tn1);
02391 OP_srcpos(new_op) = OP_srcpos(op);
02392 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND], NULL, opnd_tninfo[l0_opnd2_idx] );
02393 BB_Insert_Op_After(OP_bb(op), op, new_op);
02394 if (EBO_Trace_Optimization) fprintf(TFile,"Replace sub with sub_i\n");
02395 return TRUE;
02396 }
02397
02398 if (opcode == TOP_and) {
02399 if (ISA_LC_Value_In_Class (const_val, LC_i8)) {
02400 OP *new_op;
02401 if (EBO_Trace_Optimization) fprintf(TFile,"replace and with and_i\n");
02402 new_op = Mk_OP(TOP_and_i, tnr, OP_opnd(op,OP_PREDICATE_OPND),
02403 Gen_Literal_TN(const_val, TN_size(tn1)), tn1);
02404 OP_srcpos(new_op) = OP_srcpos(op);
02405 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND],
02406 NULL, opnd_tninfo[l0_opnd2_idx]);
02407 BB_Insert_Op_After(OP_bb(op), op, new_op);
02408 return TRUE;
02409 } else if (!EBO_in_loop) {
02410
02411
02412
02413 OPS ops = OPS_EMPTY;
02414 if (Expand_Special_And_Immed (tnr, tn1, const_val, &ops)) {
02415 if (EBO_Trace_Optimization) fprintf(TFile,"replace and with bit move\n");
02416 Set_OP_opnd(OPS_first(&ops), OP_PREDICATE_OPND, OP_opnd(op,OP_PREDICATE_OPND));
02417 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
02418 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
02419 return TRUE;
02420 }
02421 }
02422 }
02423
02424 if (opcode == TOP_andcm) {
02425 if (ISA_LC_Value_In_Class (const_val, LC_i8)) {
02426 OP *new_op;
02427 if (EBO_Trace_Optimization) fprintf(TFile,"replace andcm with andcm_i\n");
02428 new_op = Mk_OP(TOP_andcm_i, tnr, OP_opnd(op,OP_PREDICATE_OPND),
02429 Gen_Literal_TN(const_val, TN_size(tn1)), tn1);
02430 OP_srcpos(new_op) = OP_srcpos(op);
02431 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND],
02432 NULL, opnd_tninfo[l0_opnd2_idx]);
02433 BB_Insert_Op_After(OP_bb(op), op, new_op);
02434 return TRUE;
02435 }
02436 }
02437
02438 if ((opcode == TOP_or) &&
02439 (ISA_LC_Value_In_Class (const_val, LC_i8))) {
02440 OP *new_op;
02441 if (EBO_Trace_Optimization) fprintf(TFile,"replace or with or_i\n");
02442 new_op = Mk_OP(TOP_or_i, tnr, OP_opnd(op,OP_PREDICATE_OPND),
02443 Gen_Literal_TN(const_val, TN_size(tn1)), tn1);
02444 OP_srcpos(new_op) = OP_srcpos(op);
02445 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND], NULL, opnd_tninfo[l0_opnd2_idx]);
02446 BB_Insert_Op_After(OP_bb(op), op, new_op);
02447 return TRUE;
02448 }
02449
02450 if ((opcode == TOP_xor) &&
02451 (ISA_LC_Value_In_Class (const_val, LC_i8))) {
02452 OP *new_op;
02453 if (EBO_Trace_Optimization) fprintf(TFile,"replace xor with xor_i\n");
02454 new_op = Mk_OP(TOP_xor_i, tnr, OP_opnd(op,OP_PREDICATE_OPND),
02455 Gen_Literal_TN(const_val, TN_size(tn1)), tn1);
02456 OP_srcpos(new_op) = OP_srcpos(op);
02457 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND], NULL, opnd_tninfo[l0_opnd2_idx]);
02458 BB_Insert_Op_After(OP_bb(op), op, new_op);
02459 return TRUE;
02460 }
02461
02462 if ((opcode == TOP_dep) &&
02463 ((const_val == 0) || (const_val == ~0))) {
02464 OP *new_op;
02465 if (EBO_Trace_Optimization) fprintf(TFile,"replace dep with dep_i\n");
02466 new_op = Mk_OP(TOP_dep_i, tnr, OP_opnd(op,OP_PREDICATE_OPND),
02467 Gen_Literal_TN(const_val, TN_size(tn1)), tn1,
02468 OP_opnd(op,3), OP_opnd(op,4));
02469 OP_srcpos(new_op) = OP_srcpos(op);
02470 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND],
02471 NULL, opnd_tninfo[l0_opnd2_idx], NULL, NULL);
02472 BB_Insert_Op_After(OP_bb(op), op, new_op);
02473 return TRUE;
02474 }
02475
02476 if ((opcode == TOP_dep_z) &&
02477 (ISA_LC_Value_In_Class (const_val, LC_i8))) {
02478 OP *new_op;
02479 if (EBO_Trace_Optimization) fprintf(TFile,"replace dep_z with dep_z_i\n");
02480 new_op = Mk_OP(TOP_dep_i, tnr, OP_opnd(op,OP_PREDICATE_OPND),
02481 Gen_Literal_TN(const_val, 4), OP_opnd(op,3), OP_opnd(op,4));
02482 OP_srcpos(new_op) = OP_srcpos(op);
02483 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND],
02484 NULL, NULL, NULL);
02485 BB_Insert_Op_After(OP_bb(op), op, new_op);
02486 return TRUE;
02487 }
02488
02489 if (OP_icmp(op)) {
02490 TOP new_opcode = Immediate_Compare(opcode);
02491 INT64 new_const_val = Normalize_Immediate(opcode, const_val);
02492 if (new_opcode != TOP_UNDEFINED &&
02493 TOP_Can_Have_Immediate(new_const_val, new_opcode)) {
02494 TN *r1 = OP_result(op,0);
02495 TN *r2 = OP_result(op,1);
02496 OPS ops = OPS_EMPTY;
02497 if (EBO_Trace_Optimization) fprintf(TFile,"replace cmp with cmp_i\n");
02498 Build_OP (new_opcode, r1, r2, OP_opnd(op,OP_PREDICATE_OPND),
02499 Gen_Literal_TN(new_const_val, TN_size(tn1)), tn1, &ops);
02500 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops), opnd_tninfo[OP_PREDICATE_OPND],
02501 NULL, opnd_tninfo[l0_opnd2_idx]);
02502 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
02503 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
02504 return TRUE;
02505 }
02506 }
02507
02508
02509
02510 if ((opcode == TOP_adds) &&
02511 (!TN_Is_Constant(tn1)) &&
02512 ISA_LC_Value_In_Class (const_val, LC_i9)) {
02513 TN *tnr = OP_result(op,0);
02514 OP *test_op = OP_prev(op);
02515 OP *memory_op = NULL;
02516 EBO_OP_INFO *memory_opinfo = NULL;
02517 TOP memory_opcode = TOP_add;
02518 EBO_TN_INFO *memory_index = NULL;
02519 EBO_TN_INFO *memory_r1 = NULL;
02520 EBO_TN_INFO *memory_r2 = NULL;
02521 EBO_TN_INFO *memory_sv = NULL;
02522
02523 while (test_op) {
02524 if (OP_load(test_op) || OP_store(test_op)) {
02525 memory_op = test_op;
02526 test_op = NULL;
02527 break;
02528 }
02529 test_op = OP_prev(test_op);
02530 }
02531
02532 if (memory_op != NULL) {
02533 memory_opinfo = find_opinfo_entry (memory_op);
02534 memory_opcode = OP_code(memory_op);
02535 if (memory_opinfo != NULL) {
02536 memory_index = memory_opinfo->actual_opnd[TOP_Find_Operand_Use(memory_opcode, OU_base)];
02537 if (OP_load(memory_op)) {
02538 memory_r1 = memory_opinfo->actual_rslt[0];
02539 if (OP_results(memory_op) > 1) {
02540 memory_r2 = memory_opinfo->actual_rslt[1];
02541 }
02542 } else if (OP_store(memory_op)) {
02543 memory_sv = memory_opinfo->actual_opnd[TOP_Find_Operand_Use(memory_opcode, OU_storeval)];
02544 }
02545 }
02546 }
02547
02548
02549 if ((memory_opinfo != NULL) &&
02550 ((TN_Is_Constant(OP_opnd(op,OP_PREDICATE_OPND)) &&
02551 TN_Is_Constant(OP_opnd(memory_op,OP_PREDICATE_OPND)) &&
02552 (TN_Value(OP_opnd(op,OP_PREDICATE_OPND)) == TN_Value(OP_opnd(memory_op,OP_PREDICATE_OPND)))) ||
02553 (!TN_Is_Constant(OP_opnd(op,OP_PREDICATE_OPND)) &&
02554 !TN_Is_Constant(OP_opnd(memory_op,OP_PREDICATE_OPND)) &&
02555 EBO_tn_available(bb, memory_opinfo->actual_opnd[OP_PREDICATE_OPND]) &&
02556 tn_registers_identical(OP_opnd(op,OP_PREDICATE_OPND), OP_opnd(memory_op,OP_PREDICATE_OPND)))) &&
02557 (OP_memory(memory_op)) &&
02558 ((memory_index != NULL) &&
02559 EBO_tn_available(bb, memory_index) &&
02560 tn_registers_identical(memory_index->local_tn, tn1)) &&
02561 ((memory_r1 == NULL) || (memory_r1->reference_count == 0)) &&
02562 ((memory_r2 == NULL) || (memory_r2->reference_count == 0)) &&
02563 ((memory_sv == NULL) || EBO_tn_available(bb, memory_sv)) &&
02564 ((memory_sv == NULL) || !tn_registers_identical(tnr, memory_sv->local_tn))) {
02565 TOP new_opcode;
02566 BOOL use_increment = TRUE;
02567
02568 switch (memory_opcode) {
02569 case TOP_ld1: new_opcode = TOP_ld1_i; break;
02570 case TOP_ld2: new_opcode = TOP_ld2_i; break;
02571 case TOP_ld4: new_opcode = TOP_ld4_i; break;
02572 case TOP_ld8: new_opcode = TOP_ld8_i; break;
02573 case TOP_ld8_fill: new_opcode = TOP_ld8_i_fill; break;
02574 case TOP_ldfs: new_opcode = TOP_ldfs_i; break;
02575 case TOP_ldfd: new_opcode = TOP_ldfd_i; break;
02576 case TOP_ldfe: new_opcode = TOP_ldfe_i; break;
02577 case TOP_ldf8: new_opcode = TOP_ldf8_i; break;
02578 case TOP_ldf_fill: new_opcode = TOP_ldf_i_fill; break;
02579 case TOP_ldfps:
02580 new_opcode = TOP_ldfps_i;
02581 if (CGTARG_Mem_Ref_Bytes(memory_op) != const_val) use_increment = FALSE;
02582 break;
02583 case TOP_ldfpd:
02584 new_opcode = TOP_ldfpd_i;
02585 if (CGTARG_Mem_Ref_Bytes(memory_op) != const_val) use_increment = FALSE;
02586 break;
02587 case TOP_ldfp8:
02588 new_opcode = TOP_ldfp8_i;
02589 if (CGTARG_Mem_Ref_Bytes(memory_op) != const_val) use_increment = FALSE;
02590 break;
02591 case TOP_lfetch: new_opcode = TOP_lfetch_i; break;
02592 case TOP_lfetch_excl: new_opcode = TOP_lfetch_i_excl; break;
02593 case TOP_lfetch_fault: new_opcode = TOP_lfetch_i_fault; break;
02594 case TOP_lfetch_fault_excl: new_opcode = TOP_lfetch_i_fault_excl; break;
02595 case TOP_st1: new_opcode = TOP_st1_i; break;
02596 case TOP_st2: new_opcode = TOP_st2_i; break;
02597 case TOP_st4: new_opcode = TOP_st4_i; break;
02598 case TOP_st8: new_opcode = TOP_st8_i; break;
02599 case TOP_st8_spill: new_opcode = TOP_st8_i_spill; break;
02600 case TOP_stfs: new_opcode = TOP_stfs_i; break;
02601 case TOP_stfd: new_opcode = TOP_stfd_i; break;
02602 case TOP_stfe: new_opcode = TOP_stfe_i; break;
02603 case TOP_stf8: new_opcode = TOP_stf8_i; break;
02604 case TOP_stf_spill: new_opcode = TOP_stf_i_spill; break;
02605 case TOP_ldfps_i:
02606 case TOP_ldfpd_i:
02607 case TOP_ldfp8_i:
02608 use_increment = FALSE; break;
02609 default:
02610 if (TOP_Find_Operand_Use(memory_opcode, OU_postincr) >= 0) {
02611 new_opcode = memory_opcode;
02612 const_val += TN_Value(OP_opnd(memory_op,TOP_Find_Operand_Use(memory_opcode, OU_postincr)));
02613 break;
02614 }
02615 use_increment = FALSE; break;
02616 }
02617
02618
02619 if (EBO_in_pre || EBO_in_loop) use_increment = FALSE;
02620
02621
02622 if (!EBO_in_peep) use_increment = FALSE;
02623
02624
02625
02626 if (OP_load (memory_op) && OP_speculative(memory_op)) {
02627 use_increment = FALSE;
02628 }
02629
02630
02631
02632
02633 if (use_increment && OP_load(memory_op) &&
02634 !tn_registers_identical(tnr, tn1)) {
02635 use_increment = FALSE;
02636 }
02637
02638 if (use_increment &&
02639 (TOP_Find_Operand_Use(new_opcode, OU_postincr) >= 0)) {
02640 OP *new_op;
02641 OPS ops = OPS_EMPTY;
02642
02643 if (!tn_registers_identical(tnr, tn1)) {
02644 EBO_Exp_COPY(OP_opnd(op,OP_PREDICATE_OPND), tnr, tn1, &ops);
02645 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops),
02646 opnd_tninfo[OP_PREDICATE_OPND],
02647 opnd_tninfo[l0_opnd2_idx]);
02648 }
02649
02650 TN *save_opnds[OP_MAX_FIXED_OPNDS];
02651 INT i;
02652
02653 Is_True(OP_opnds(memory_op) <= OP_MAX_FIXED_OPNDS,
02654 ("save_opnds is too small for %s", TOP_Name(OP_code(memory_op))));
02655 for (i=0; i<OP_opnds(memory_op); i++) save_opnds[i] = OP_opnd(memory_op, i);
02656
02657 if (OP_load(memory_op)) {
02658 if (OP_results(memory_op) == 1) {
02659 new_op = Mk_OP (new_opcode, OP_result(memory_op, 0), tnr,
02660 save_opnds[0], save_opnds[1], save_opnds[2], NULL, NULL);
02661 } else {
02662 new_op = Mk_OP (new_opcode, OP_result(memory_op, 0), OP_result(memory_op, 1), tnr,
02663 save_opnds[0], save_opnds[1], save_opnds[2], NULL, NULL);
02664 }
02665 } else {
02666 if (OP_opnds(memory_op) == 4) {
02667 new_op = Mk_OP(new_opcode, tnr, save_opnds[0], save_opnds[1], save_opnds[2], NULL, NULL);
02668 } else {
02669 new_op = Mk_OP(new_opcode, tnr, save_opnds[0], save_opnds[1], save_opnds[2], NULL, NULL, NULL);
02670 }
02671
02672 Set_OP_opnd(new_op, TOP_Find_Operand_Use(new_opcode, OU_storeval),
02673 save_opnds[TOP_Find_Operand_Use(memory_opcode, OU_storeval)]);
02674 }
02675
02676 Set_OP_opnd(new_op, TOP_Find_Operand_Use(new_opcode, OU_base), tnr);
02677 Set_OP_opnd(new_op, TOP_Find_Operand_Use(new_opcode, OU_postincr), Gen_Literal_TN(const_val, 4));
02678 Copy_WN_For_Memory_OP (new_op, memory_op);
02679 OP_srcpos(new_op) = OP_srcpos(memory_op);
02680 OPS_Append_Op( &ops, new_op);
02681
02682 BB_Insert_Ops(bb, op, &ops, FALSE);
02683
02684 remove_op (memory_opinfo);
02685 OP_Change_To_Noop(memory_op);
02686 memory_opinfo->in_op = NULL;
02687 memory_opinfo->in_bb = NULL;
02688
02689 if (EBO_Trace_Optimization) fprintf(TFile,"memory op merged with increment to produce %s (inc=%lld).\n",
02690 TOP_Name(new_opcode),const_val);
02691 return TRUE;
02692 }
02693 }
02694 }
02695
02696 tninfo = opnd_tninfo[l0_opnd2_idx];
02697 if (tninfo == NULL) return FALSE;
02698 pred_op = tninfo->in_op;
02699 if (pred_op == NULL) return FALSE;
02700 pred_opcode = OP_code(pred_op);
02701 if (pred_opcode == TOP_spadjust) return FALSE;
02702 pred_opinfo = locate_opinfo_entry (tninfo);
02703 if (pred_opinfo == NULL) return FALSE;
02704
02705
02706 if (OP_load(pred_op)) {
02707 if (OP_iand(op)) {
02708 if (((pred_opcode == TOP_ld1) &&
02709 (const_val == (~((~0) << 8)))) ||
02710 ((pred_opcode == TOP_ld2) &&
02711 (const_val == (~((~0) << 16))))) {
02712
02713 OPS ops = OPS_EMPTY;
02714 if (EBO_Trace_Optimization) fprintf(TFile,"no need to mask after load\n");
02715 EBO_Exp_COPY((OP_has_predicate(op)?OP_opnd(op,OP_PREDICATE_OPND):NULL),
02716 tnr, tn1, &ops);
02717 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops),
02718 OP_has_predicate(op)?opnd_tninfo[OP_PREDICATE_OPND]:NULL,
02719 opnd_tninfo[l0_opnd2_idx]);
02720 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
02721 BB_Insert_Ops(bb, op, &ops, FALSE);
02722 return TRUE;
02723 }
02724 }
02725 return FALSE;
02726 }
02727
02728 if ((opcode == TOP_dep) ||
02729 (opcode == TOP_dep_i)) {
02730
02731
02732 if ((pred_opcode == TOP_dep) ||
02733 (pred_opcode == TOP_dep_i)) {
02734 TN *pred_insert = OP_opnd(pred_op,1);
02735 EBO_TN_INFO *pred_insert_tninfo = pred_opinfo->actual_opnd[1];
02736 TN *pred_tn = OP_opnd(pred_op,2);
02737 INT pred_start = TN_Value(OP_opnd(pred_op,3));
02738 INT pred_length = TN_Value(OP_opnd(pred_op,4));
02739 INT op_start = TN_Value(OP_opnd(op,3));
02740 INT op_length = TN_Value(OP_opnd(op,4));
02741
02742
02743 if (pred_opinfo->optimal_opnd[1] != NULL) {
02744 pred_insert_tninfo = pred_opinfo->optimal_opnd[1];
02745 pred_insert = pred_insert_tninfo->local_tn;
02746 }
02747 if ((pred_insert_tninfo != NULL) &&
02748 (pred_insert_tninfo->replacement_tn != NULL)) {
02749 pred_insert = pred_insert_tninfo->replacement_tn;
02750 pred_insert_tninfo = pred_insert_tninfo->replacement_tninfo;
02751 }
02752
02753
02754
02755
02756
02757
02758
02759 if (has_assigned_reg(tnr) &&
02760 TNs_Are_Equivalent(tnr,pred_tn)) return FALSE;
02761
02762 if (TN_Is_Constant(pred_insert) &&
02763 ((pred_start+pred_length) == op_start) &&
02764 ((op_length+pred_length) < 16)) {
02765
02766 OPS ops = OPS_EMPTY;
02767 OP *new_op;
02768 TN *predicate_tn = OP_opnd(op,OP_PREDICATE_OPND);
02769 TN *new_const_tn = has_assigned_reg(tnr) ? tnr : Dup_TN_Even_If_Dedicated(tnr);
02770 UINT64 mask;
02771
02772 mask = (~0);
02773 mask = mask << op_length;
02774 const_val = (const_val & ~mask) << pred_length;
02775
02776 mask = (~0);
02777 mask = mask << pred_length;
02778 const_val |= (TN_Value(pred_insert) & ~mask);
02779 if (EBO_Trace_Optimization) fprintf(TFile,"combine dep to the left of previous dep\n");
02780 EBO_Exp_COPY(predicate_tn, new_const_tn, Gen_Literal_TN(const_val, TN_size(tnr)), &ops);
02781 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops),
02782 opnd_tninfo[OP_PREDICATE_OPND],
02783 pred_opinfo->actual_opnd[2]);
02784 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
02785
02786 Build_OP(TOP_dep, tnr, predicate_tn, new_const_tn, OP_opnd(pred_op,2),
02787 OP_opnd(pred_op,3), Gen_Literal_TN(op_length+pred_length, 4), &ops);
02788 if (predicate_tn != True_TN) Set_OP_cond_def_kind(OPS_last(&ops), OP_PREDICATED_DEF);
02789 OP_srcpos(OPS_last(&ops)) = OP_srcpos(op);
02790 if (EBO_in_loop) EBO_Set_OP_omega (OPS_last(&ops),
02791 opnd_tninfo[OP_PREDICATE_OPND], NULL,
02792 pred_opinfo->actual_opnd[2]);
02793
02794 BB_Insert_Ops(bb, op, &ops, FALSE);
02795 return TRUE;
02796 }
02797
02798 if (TN_Is_Constant(pred_insert) &&
02799 ((op_start+op_length) == pred_start) &&
02800 ((op_length+pred_length) < 16)) {
02801
02802 OPS ops = OPS_EMPTY;
02803 OP *new_op;
02804 TN *predicate_tn = OP_opnd(op,OP_PREDICATE_OPND);
02805 TN *new_const_tn = has_assigned_reg(tnr) ? tnr : Dup_TN_Even_If_Dedicated(tnr);
02806 UINT64 mask;
02807
02808 mask = (~0);
02809 mask = mask << op_length;
02810 const_val = (const_val & ~mask);
02811
02812 mask = (~0);
02813 mask = mask << pred_length;
02814 const_val |= (TN_Value(pred_insert) & ~mask) << op_length;
02815 if (EBO_Trace_Optimization) fprintf(TFile,"combine dep to the right of previous dep\n");
02816 EBO_Exp_COPY(predicate_tn, new_const_tn, Gen_Literal_TN(const_val, TN_size(tnr)), &ops);
02817 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops),
02818 opnd_tninfo[OP_PREDICATE_OPND],
02819 pred_opinfo->actual_opnd[2]);
02820 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
02821
02822 Build_OP(TOP_dep, tnr, predicate_tn, new_const_tn, OP_opnd(pred_op,2),
02823 OP_opnd(op,3), Gen_Literal_TN(op_length+pred_length, 4), &ops);
02824 if (predicate_tn != True_TN) Set_OP_cond_def_kind(OPS_last(&ops), OP_PREDICATED_DEF);
02825 OP_srcpos(OPS_last(&ops)) = OP_srcpos(op);
02826 if (EBO_in_loop) EBO_Set_OP_omega (OPS_last(&ops),
02827 opnd_tninfo[OP_PREDICATE_OPND], NULL,
02828 pred_opinfo->actual_opnd[2]);
02829
02830 BB_Insert_Ops(bb, op, &ops, FALSE);
02831 return TRUE;
02832 }
02833 }
02834 }
02835
02836
02837
02838 if (TOP_Find_Operand_Use(pred_opcode,OU_opnd2) >= 0) {
02839 INT ptn0_idx = TOP_Find_Operand_Use(pred_opcode,OU_opnd1);
02840 INT ptn1_idx = TOP_Find_Operand_Use(pred_opcode,OU_opnd2);
02841 TN *ptn0 = OP_opnd(pred_op, ptn0_idx);
02842 TN *ptn1 = OP_opnd(pred_op, ptn1_idx);
02843 EBO_TN_INFO *ptn0_tninfo;
02844 EBO_TN_INFO *ptn1_tninfo;
02845 INT64 pred_val = 0;
02846
02847 OP *new_op;
02848 TOP new_opcode;
02849 INT64 new_const_val;
02850
02851 ptn0_tninfo = pred_opinfo->actual_opnd[ptn0_idx];
02852 ptn1_tninfo = pred_opinfo->actual_opnd[ptn1_idx];
02853
02854
02855 if (!(TN_Is_Constant(ptn0) || EBO_tn_available (bb, ptn0_tninfo)) ||
02856 !(TN_Is_Constant(ptn1) || EBO_tn_available (bb, ptn1_tninfo))) return FALSE;
02857
02858 if (opcode == TOP_adds) {
02859 if (((pred_opcode == TOP_add) && (const_val == 1)) ||
02860 ((pred_opcode == TOP_sub) && (const_val == -1))) {
02861
02862 new_opcode = (pred_opcode == TOP_add) ? TOP_add_1 : TOP_sub_1;
02863 new_op = Mk_OP (new_opcode, tnr, OP_opnd(op,OP_PREDICATE_OPND), ptn0, ptn1);
02864 OP_srcpos(new_op) = OP_srcpos(op);
02865 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND], ptn0_tninfo, ptn1_tninfo );
02866 BB_Insert_Op_After(bb, op, new_op);
02867 if (EBO_Trace_Optimization) fprintf(TFile,"combine add and add1\n");
02868 return TRUE;
02869 }
02870 }
02871
02872 if (TN_Is_Constant(ptn1)) {
02873 } else if (TN_Is_Constant(ptn0) &&
02874 (OP_iadd(pred_op) || OP_ior(pred_op) || OP_iand(pred_op))) {
02875
02876 TN *s = ptn0;
02877 ptn0 = ptn1;
02878 ptn0_tninfo = ptn1_tninfo;
02879 ptn1 = s;
02880 } else {
02881 return FALSE;
02882 }
02883
02884 pred_val = TN_is_symbol(ptn1) ? TN_offset(ptn1) : TN_Value(ptn1);
02885
02886
02887 if (OP_icmp(op) && OP_iadd(pred_op) && !TN_is_symbol(ptn1)) {
02888 INT cmp_size;
02889
02890 if ((pred_val != 0) &&
02891 ((opcode == TOP_cmp4_ltu) ||
02892 (opcode == TOP_cmp4_ltu_unc) ||
02893 (opcode == TOP_cmp4_leu) ||
02894 (opcode == TOP_cmp4_leu_unc) ||
02895 (opcode == TOP_cmp4_gtu) ||
02896 (opcode == TOP_cmp4_gtu_unc) ||
02897 (opcode == TOP_cmp4_geu) ||
02898 (opcode == TOP_cmp4_geu_unc) ||
02899 (opcode == TOP_cmp_ltu) ||
02900 (opcode == TOP_cmp_ltu_unc) ||
02901 (opcode == TOP_cmp_leu) ||
02902 (opcode == TOP_cmp_leu_unc) ||
02903 (opcode == TOP_cmp_gtu) ||
02904 (opcode == TOP_cmp_gtu_unc) ||
02905 (opcode == TOP_cmp_geu) ||
02906 (opcode == TOP_cmp_geu_unc) ||
02907 (opcode == TOP_cmp4_i_ltu) ||
02908 (opcode == TOP_cmp4_i_ltu_unc) ||
02909 (opcode == TOP_cmp4_i_leu) ||
02910 (opcode == TOP_cmp4_i_leu_unc) ||
02911 (opcode == TOP_cmp4_i_gtu) ||
02912 (opcode == TOP_cmp4_i_gtu_unc) ||
02913 (opcode == TOP_cmp4_i_geu) ||
02914 (opcode == TOP_cmp4_i_geu_unc) ||
02915 (opcode == TOP_cmp_i_ltu) ||
02916 (opcode == TOP_cmp_i_ltu_unc) ||
02917 (opcode == TOP_cmp_i_leu) ||
02918 (opcode == TOP_cmp_i_leu_unc) ||
02919 (opcode == TOP_cmp_i_gtu) ||
02920 (opcode == TOP_cmp_i_gtu_unc) ||
02921 (opcode == TOP_cmp_i_geu) ||
02922 (opcode == TOP_cmp_i_geu_unc))) {
02923
02924 return FALSE;
02925 }
02926 new_const_val = const_val - pred_val;
02927
02928 switch (opcode) {
02929 case TOP_cmp4_i_eq:
02930 case TOP_cmp4_i_eq_unc:
02931 case TOP_cmp4_i_eq_and:
02932 case TOP_cmp4_i_eq_or:
02933 case TOP_cmp4_i_eq_or_andcm:
02934 case TOP_cmp4_i_ne_and:
02935 case TOP_cmp4_i_ne_or:
02936 case TOP_cmp4_i_ne_or_andcm:
02937 case TOP_cmp4_i_lt:
02938 case TOP_cmp4_i_lt_unc:
02939 case TOP_cmp4_i_ltu:
02940 case TOP_cmp4_i_ltu_unc:
02941 case TOP_cmp4_i_eq_orcm:
02942 case TOP_cmp4_i_eq_andcm:
02943 case TOP_cmp4_i_eq_and_orcm:
02944 case TOP_cmp4_i_ne:
02945 case TOP_cmp4_i_ne_unc:
02946 case TOP_cmp4_i_ne_orcm:
02947 case TOP_cmp4_i_ne_andcm:
02948 case TOP_cmp4_i_ne_and_orcm:
02949 case TOP_cmp4_i_le:
02950 case TOP_cmp4_i_le_unc:
02951 case TOP_cmp4_i_gt:
02952 case TOP_cmp4_i_gt_unc:
02953 case TOP_cmp4_i_ge:
02954 case TOP_cmp4_i_ge_unc:
02955 case TOP_cmp4_i_leu:
02956 case TOP_cmp4_i_leu_unc:
02957 case TOP_cmp4_i_gtu:
02958 case TOP_cmp4_i_gtu_unc:
02959 case TOP_cmp4_i_geu:
02960 case TOP_cmp4_i_geu_unc:
02961 new_const_val = Normalize_Immediate(opcode, new_const_val);
02962 case TOP_cmp_i_eq:
02963 case TOP_cmp_i_eq_unc:
02964 case TOP_cmp_i_eq_and:
02965 case TOP_cmp_i_eq_or:
02966 case TOP_cmp_i_eq_or_andcm:
02967 case TOP_cmp_i_ne_and:
02968 case TOP_cmp_i_ne_or:
02969 case TOP_cmp_i_ne_or_andcm:
02970 case TOP_cmp_i_lt:
02971 case TOP_cmp_i_lt_unc:
02972 case TOP_cmp_i_ltu:
02973 case TOP_cmp_i_ltu_unc:
02974 case TOP_cmp_i_eq_orcm:
02975 case TOP_cmp_i_eq_andcm:
02976 case TOP_cmp_i_eq_and_orcm:
02977 case TOP_cmp_i_ne:
02978 case TOP_cmp_i_ne_unc:
02979 case TOP_cmp_i_ne_orcm:
02980 case TOP_cmp_i_ne_andcm:
02981 case TOP_cmp_i_ne_and_orcm:
02982 case TOP_cmp_i_le:
02983 case TOP_cmp_i_le_unc:
02984 case TOP_cmp_i_gt:
02985 case TOP_cmp_i_gt_unc:
02986 case TOP_cmp_i_ge:
02987 case TOP_cmp_i_ge_unc:
02988 case TOP_cmp_i_leu:
02989 case TOP_cmp_i_leu_unc:
02990 case TOP_cmp_i_gtu:
02991 case TOP_cmp_i_gtu_unc:
02992 case TOP_cmp_i_geu:
02993 case TOP_cmp_i_geu_unc:
02994 if (TOP_Can_Have_Immediate(new_const_val, opcode)) {
02995 OPS ops = OPS_EMPTY;
02996 if (EBO_Trace_Optimization) fprintf(TFile,"merge cmp_i with add: (%lld)\n",new_const_val);
02997 Build_OP (opcode, OP_result(op,0), OP_result(op,1), OP_opnd(op,OP_PREDICATE_OPND),
02998 Gen_Literal_TN(new_const_val, TN_size(tn1)), ptn0, &ops);
02999 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops), opnd_tninfo[OP_PREDICATE_OPND],
03000 NULL, ptn0_tninfo );
03001 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
03002 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
03003 return TRUE;
03004 }
03005 break;
03006 case TOP_cmp4_lt:
03007 case TOP_cmp4_lt_unc:
03008 case TOP_cmp4_le:
03009 case TOP_cmp4_le_unc:
03010 case TOP_cmp4_gt:
03011 case TOP_cmp4_gt_unc:
03012 case TOP_cmp4_ge:
03013 case TOP_cmp4_ge_unc:
03014 case TOP_cmp_lt:
03015 case TOP_cmp_lt_unc:
03016 case TOP_cmp_le:
03017 case TOP_cmp_le_unc:
03018 case TOP_cmp_gt:
03019 case TOP_cmp_gt_unc:
03020 case TOP_cmp_ge:
03021 case TOP_cmp_ge_unc:
03022 cmp_size = EBO_bit_length (op);
03023 if ((cmp_size > 1) &&
03024 (((const_val >> (cmp_size-1)) &1) != ((new_const_val >> (cmp_size-1)) &1))) {
03025
03026 break;
03027 }
03028 default:
03029 if (!has_assigned_reg(tn1)) {
03030 OPS ops = OPS_EMPTY;
03031 TN *tnr = Dup_TN_Even_If_Dedicated (OP_opnd(op,1));
03032 TN *tnc = Gen_Literal_TN(new_const_val, TN_size(tn1));
03033 if (EBO_Trace_Optimization) fprintf(TFile,"merge cmp with add (0x%llx)\n",new_const_val);
03034 Expand_Immediate (tnr, tnc, (new_const_val < 0) ? TRUE : FALSE, &ops);
03035 if (OP_has_predicate(op)) {
03036 EBO_OPS_predicate (OP_opnd(op, OP_PREDICATE_OPND), &ops);
03037 }
03038 if (EBO_in_loop) EBO_OPS_omega (&ops, OP_has_predicate(op)?opnd_tninfo[OP_PREDICATE_OPND]:NULL);
03039 Build_OP (opcode, OP_result(op,0), OP_result(op,1), OP_opnd(op,OP_PREDICATE_OPND),
03040 tnr, ptn0, &ops);
03041 if (EBO_in_loop) EBO_Set_OP_omega (OPS_last(&ops), opnd_tninfo[OP_PREDICATE_OPND],
03042 NULL, ptn0_tninfo );
03043 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
03044 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
03045 return TRUE;
03046 }
03047 break;
03048 }
03049
03050 }
03051
03052
03053 if (OP_iadd(op) && OP_iadd(pred_op)) {
03054 new_const_val = pred_val + const_val;
03055
03056 if (ISA_LC_Value_In_Class (new_const_val, LC_i22)) {
03057 TN *new_tn;
03058 new_opcode = (ISA_LC_Value_In_Class (new_const_val, LC_i14)) ? TOP_adds : TOP_addl;
03059 if (new_opcode == TOP_addl) return FALSE;
03060
03061 if (TN_is_symbol(ptn1)) {
03062 ST *st = TN_var(ptn1);
03063 ST *base_st;
03064 INT64 base_ofst;
03065 INT32 rel = TN_relocs(ptn1);
03066
03067 Base_Symbol_And_Offset (st, &base_st, &base_ofst);
03068 if (ST_on_stack(st) &&
03069 ((ST_sclass(st) == SCLASS_AUTO) ||
03070 (EBO_in_peep && (ST_sclass(st) == SCLASS_FORMAL))) &&
03071 ISA_LC_Value_In_Class (new_const_val+base_ofst, LC_i14)) {
03072 new_tn = Gen_Symbol_TN(st, new_const_val, rel);
03073 } else return FALSE;
03074 } else {
03075 new_tn = Gen_Literal_TN(new_const_val, TN_size(tn1));
03076 }
03077
03078 new_op = Mk_OP (new_opcode, tnr, OP_opnd(op,OP_PREDICATE_OPND), new_tn, ptn0);
03079 OP_srcpos(new_op) = OP_srcpos(op);
03080 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND], NULL, ptn0_tninfo );
03081 BB_Insert_Op_After(bb, op, new_op);
03082 if (EBO_Trace_Optimization) fprintf(TFile,"combine immediate adds\n");
03083 return TRUE;
03084 }
03085
03086 return FALSE;
03087 }
03088
03089 if (TN_is_symbol(ptn1)) return FALSE;
03090
03091 if (pred_val == const_val) {
03092
03093
03094 if ((OP_iand(op) && OP_iand(pred_op) && (const_val != ~0)) ||
03095 (OP_ior(op) && OP_ior(pred_op) && (const_val != 0))) {
03096 OPS ops = OPS_EMPTY;
03097 if (EBO_Trace_Optimization) fprintf(TFile,"replace redundant and/or\n");
03098 EBO_Exp_COPY((OP_has_predicate(op)?OP_opnd(op,OP_PREDICATE_OPND):NULL),
03099 tnr, OP_result(pred_op, 0), &ops);
03100 if (EBO_in_loop) EBO_OPS_omega (&ops, OP_has_predicate(op)?opnd_tninfo[OP_PREDICATE_OPND]:NULL);
03101 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
03102 BB_Insert_Ops(bb, op, &ops, FALSE);
03103 return TRUE;
03104 }
03105
03106 }
03107
03108 } else if (((const_val >> EBO_bit_length(pred_op)) == 0) &&
03109 ((pred_opcode == TOP_sxt1) || (pred_opcode == TOP_sxt2) || (pred_opcode == TOP_sxt4) ||
03110 (pred_opcode == TOP_zxt1) || (pred_opcode == TOP_zxt2) || (pred_opcode == TOP_zxt4)) &&
03111 ((opcode == TOP_cmp_eq) || (opcode == TOP_cmp_eq_unc) ||
03112 (opcode == TOP_cmp_i_eq) || (opcode == TOP_cmp_i_eq_unc) ||
03113 (opcode == TOP_cmp_ne) || (opcode == TOP_cmp_ne_unc) ||
03114 (opcode == TOP_cmp_i_ne) || (opcode == TOP_cmp_i_ne_unc) ||
03115 (opcode == TOP_cmp4_eq) || (opcode == TOP_cmp4_eq_unc) ||
03116 (opcode == TOP_cmp4_i_eq) || (opcode == TOP_cmp4_i_eq_unc) ||
03117 (opcode == TOP_cmp4_ne) || (opcode == TOP_cmp4_ne_unc) ||
03118 (opcode == TOP_cmp4_i_ne) || (opcode == TOP_cmp4_i_ne_unc))) {
03119
03120 INT ptn0_idx = 1;
03121 TN *ptn0 = OP_opnd(pred_op, ptn0_idx);
03122 EBO_TN_INFO *ptn0_tninfo;
03123
03124 OP *new_op;
03125 TOP new_opcode;
03126 INT64 new_const_val;
03127
03128 ptn0_tninfo = pred_opinfo->actual_opnd[ptn0_idx];
03129
03130
03131 if ((ptn0_tninfo == NULL) ||
03132 (ptn0_tninfo->in_op == NULL) ||
03133 !EBO_tn_available (bb, ptn0_tninfo)) return FALSE;
03134
03135
03136 OP *pred_pred_op = ptn0_tninfo->in_op;
03137
03138
03139 if (!OP_load(pred_pred_op)) return FALSE;
03140
03141
03142 if (EBO_bit_length(pred_op) != EBO_bit_length(pred_pred_op)) return FALSE;
03143
03144
03145 new_op = Dup_OP (op);
03146 Set_OP_opnd (new_op, l0_opnd2_idx, ptn0);
03147 OP_srcpos(new_op) = OP_srcpos(op);
03148 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND], NULL, ptn0_tninfo );
03149 BB_Insert_Op_After(bb, op, new_op);
03150 if (EBO_Trace_Optimization) fprintf(TFile,"sign-extension in load-extend-cmp sequence is not needed\n");
03151 return TRUE;
03152 }
03153
03154 return FALSE;
03155 }
03156
03157
03158
03159
03160
03161
03162
03163 BOOL
03164 Constant_Operand1 (OP *op,
03165 TN **opnd_tn,
03166 EBO_TN_INFO **opnd_tninfo)
03167 {
03168 BB *bb = OP_bb(op);
03169 INT opndnum = OP_opnds(op);
03170 EBO_TN_INFO *tninfo;
03171
03172 TOP opcode = OP_code(op);
03173 TN *tnr = OP_result(op,0);
03174 INT l0_opnd1_idx;
03175 INT l0_opnd2_idx;
03176 TN *tn0;
03177 TN *tn1;
03178 INT64 const_val;
03179
03180 OP *pred_op;
03181 TOP pred_opcode;
03182 EBO_OP_INFO *pred_opinfo;
03183
03184 if (EBO_Trace_Execution) {
03185 #pragma mips_frequency_hint NEVER
03186 INT i;
03187 fprintf(TFile, "%sin BB:%d special1 OP :- %s ",
03188 EBO_trace_pfx, BB_id(bb),TOP_Name(OP_code(op)));
03189 for (i = 0; i < opndnum; i++) {
03190 fprintf(TFile," ");
03191 Print_TN(opnd_tn[i],FALSE);
03192 }
03193 fprintf(TFile,"\n");
03194 }
03195
03196 if (!OP_has_predicate(op)) return FALSE;
03197 if (OP_opnds(op) < 2) return FALSE;
03198
03199 if (TN_register_class(tnr) == ISA_REGISTER_CLASS_float) {
03200 if (OP_opnds(op) < 4) return FALSE;
03201 l0_opnd1_idx = 2;
03202 l0_opnd2_idx = 3;
03203 tn0 = opnd_tn[l0_opnd1_idx];
03204 tn1 = opnd_tn[l0_opnd2_idx];
03205
03206 if (tn1 == FZero_TN) {
03207 if ((IEEE_Arithmetic >= IEEE_INEXACT) &&
03208 ((opcode == TOP_fmpy) ||
03209 (opcode == TOP_fmpy_s) ||
03210 (opcode == TOP_fmpy_d))) {
03211 OPS ops = OPS_EMPTY;
03212 if (EBO_Trace_Optimization) fprintf(TFile,"replace fmpy of 0.0 with 0.0\n");
03213 EBO_Exp_COPY((OP_has_predicate(op)?OP_opnd(op,OP_PREDICATE_OPND):NULL),
03214 tnr, FZero_TN, &ops);
03215 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops),
03216 OP_has_predicate(op)?opnd_tninfo[OP_PREDICATE_OPND]:NULL,
03217 NULL);
03218 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
03219 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
03220 return TRUE;
03221 }
03222 if ((opcode == TOP_fadd) ||
03223 (opcode == TOP_fadd_s) ||
03224 (opcode == TOP_fadd_d) ||
03225 (opcode == TOP_fsub) ||
03226 (opcode == TOP_fsub_s) ||
03227 (opcode == TOP_fsub_d)) {
03228 OPS ops = OPS_EMPTY;
03229 if (EBO_Trace_Optimization) fprintf(TFile,"replace fadd of 0.0 with tn0\n");
03230 EBO_Exp_COPY((OP_has_predicate(op)?OP_opnd(op,OP_PREDICATE_OPND):NULL),
03231 tnr, tn0, &ops);
03232 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops),
03233 OP_has_predicate(op)?opnd_tninfo[OP_PREDICATE_OPND]:NULL,
03234 opnd_tninfo[l0_opnd1_idx]);
03235 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
03236 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
03237 return TRUE;
03238 }
03239 }
03240 if (tn1 == FOne_TN) {
03241 if ((opcode == TOP_fmpy) ||
03242 (opcode == TOP_fmpy_s) ||
03243 (opcode == TOP_fmpy_d)) {
03244 OPS ops = OPS_EMPTY;
03245 if (EBO_Trace_Optimization) fprintf(TFile,"replace fmpy of 1.0 with tn0\n");
03246 EBO_Exp_COPY((OP_has_predicate(op)?OP_opnd(op,OP_PREDICATE_OPND):NULL),
03247 tnr, tn0, &ops);
03248 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops),
03249 OP_has_predicate(op)?opnd_tninfo[OP_PREDICATE_OPND]:NULL,
03250 opnd_tninfo[l0_opnd1_idx]);
03251 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
03252 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
03253 return TRUE;
03254 }
03255 }
03256 }
03257 if ((TN_register_class(tnr) != ISA_REGISTER_CLASS_integer) &&
03258 (TN_register_class(tnr) != ISA_REGISTER_CLASS_predicate)) {
03259
03260 return FALSE;
03261 }
03262
03263 l0_opnd1_idx = 1;
03264 l0_opnd2_idx = 2;
03265 tn0 = opnd_tn[l0_opnd1_idx];
03266 tn1 = opnd_tn[l0_opnd2_idx];
03267 const_val = TN_Value(tn1);
03268
03269 if (TN_is_symbol(tn1)) {
03270
03271 return FALSE;
03272 }
03273
03274 if (TN_Is_Constant(tn0)) {
03275
03276
03277
03278 return FALSE;
03279 }
03280
03281 if (((TN_register_class(tn0) != ISA_REGISTER_CLASS_integer) &&
03282 (TN_register_class(tn0) != ISA_REGISTER_CLASS_predicate)) ||
03283 (TN_is_fpu_int(tnr) != TN_is_fpu_int(tn0))) {
03284
03285 if (EBO_Trace_Data_Flow) {
03286 fprintf(TFile,"%sType mismatch between result and operand\n",EBO_trace_pfx);
03287 }
03288 return FALSE;
03289 }
03290
03291 if (const_val == 0) {
03292
03293 if ((opcode == TOP_shl) ||
03294 (opcode == TOP_shl_i) ||
03295 (opcode == TOP_shr) ||
03296 (opcode == TOP_shr_u) ||
03297 (opcode == TOP_shr_i) ||
03298 (opcode == TOP_shr_i_u)||
03299 (opcode == TOP_shrp) ||
03300 (opcode == TOP_sub) ||
03301 (opcode == TOP_sub_i)) {
03302 OPS ops = OPS_EMPTY;
03303 if (EBO_Trace_Optimization) fprintf(TFile,"replace shift/subtract of zero\n");
03304 EBO_Exp_COPY((OP_has_predicate(op)?OP_opnd(op,OP_PREDICATE_OPND):NULL),
03305 tnr, tn0, &ops);
03306 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops),
03307 OP_has_predicate(op)?opnd_tninfo[OP_PREDICATE_OPND]:NULL,
03308 opnd_tninfo[l0_opnd1_idx]);
03309 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
03310 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
03311 return TRUE;
03312 }
03313
03314 if ((opcode == TOP_and) ||
03315 (opcode == TOP_and_i)) {
03316 OPS ops = OPS_EMPTY;
03317 if (EBO_Trace_Optimization) fprintf(TFile,"replace and with zero\n");
03318 EBO_Exp_COPY((OP_has_predicate(op)?OP_opnd(op,OP_PREDICATE_OPND):NULL),
03319 tnr, Zero_TN, &ops);
03320 if (EBO_in_loop) EBO_OPS_omega (&ops, OP_has_predicate(op)?opnd_tninfo[OP_PREDICATE_OPND]:NULL);
03321 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
03322 BB_Insert_Ops(bb, op, &ops, FALSE);
03323 return TRUE;
03324 }
03325
03326 if (opcode == TOP_dep) {
03327 OP *new_op;
03328 if (EBO_Trace_Optimization) fprintf(TFile,"replace dep with dep_z\n");
03329 new_op = Mk_OP(TOP_dep_z, tnr, OP_opnd(op,OP_PREDICATE_OPND),
03330 tn0, OP_opnd(op,3), OP_opnd(op,4));
03331 OP_srcpos(new_op) = OP_srcpos(op);
03332 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND],
03333 opnd_tninfo[l0_opnd2_idx], NULL, NULL);
03334 BB_Insert_Op_After(OP_bb(op), op, new_op);
03335 return TRUE;
03336 }
03337
03338 }
03339
03340 if (const_val > 63) {
03341
03342 if ((opcode == TOP_shl) ||
03343 (opcode == TOP_shl_i) ||
03344 (opcode == TOP_shr_u) ||
03345 (opcode == TOP_shr_i_u)) {
03346 OPS ops = OPS_EMPTY;
03347 if (EBO_Trace_Optimization) fprintf(TFile,"replace shift with zero\n");
03348 EBO_Exp_COPY((OP_has_predicate(op)?OP_opnd(op,OP_PREDICATE_OPND):NULL),
03349 tnr, Zero_TN, &ops);
03350 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops),
03351 OP_has_predicate(op)?opnd_tninfo[OP_PREDICATE_OPND]:NULL,
03352 NULL);
03353 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
03354 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
03355 return TRUE;
03356 }
03357
03358 }
03359
03360 if ((opcode == TOP_add) &&
03361 (ISA_LC_Value_In_Class ( const_val, LC_i22))) {
03362 OP *new_op;
03363 TOP new_opcode = (ISA_LC_Value_In_Class (const_val, LC_i14)) ? TOP_adds : TOP_addl;
03364 if (new_opcode == TOP_addl) return FALSE;
03365
03366 new_op = Mk_OP(new_opcode, tnr, OP_opnd(op,OP_PREDICATE_OPND),
03367 Gen_Literal_TN(const_val, TN_size(tn0)), tn0);
03368 OP_srcpos(new_op) = OP_srcpos(op);
03369 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND], NULL, opnd_tninfo[l0_opnd1_idx]);
03370 BB_Insert_Op_After(OP_bb(op), op, new_op);
03371 if (EBO_Trace_Optimization) fprintf(TFile,"Reverse and replace add with adds\n");
03372 return TRUE;
03373 }
03374
03375 if ((opcode == TOP_sub) &&
03376 (ISA_LC_Value_In_Class (-const_val, LC_i22))) {
03377 OP *new_op;
03378 TOP new_opcode = (ISA_LC_Value_In_Class ( -const_val, LC_i14)) ? TOP_adds : TOP_addl;
03379 if (new_opcode == TOP_addl) return FALSE;
03380
03381 new_op = Mk_OP(new_opcode, tnr, OP_opnd(op,OP_PREDICATE_OPND),
03382 Gen_Literal_TN(-const_val, TN_size(tn0)), tn0);
03383 OP_srcpos(new_op) = OP_srcpos(op);
03384 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND], NULL, opnd_tninfo[l0_opnd1_idx]);
03385 BB_Insert_Op_After(OP_bb(op), op, new_op);
03386 if (EBO_Trace_Optimization) fprintf(TFile,"replace sub with add_i\n");
03387 return TRUE;
03388 }
03389
03390 if (opcode == TOP_and) {
03391 if (ISA_LC_Value_In_Class (const_val, LC_i8)) {
03392 OP *new_op;
03393 if (EBO_Trace_Optimization) fprintf(TFile,"replace and with and_i\n");
03394 new_op = Mk_OP(TOP_and_i, tnr, OP_opnd(op,OP_PREDICATE_OPND),
03395 Gen_Literal_TN(const_val, TN_size(tn0)), tn0);
03396 OP_srcpos(new_op) = OP_srcpos(op);
03397 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND], NULL, opnd_tninfo[l0_opnd1_idx]);
03398 BB_Insert_Op_After(OP_bb(op), op, new_op);
03399 return TRUE;
03400 } else {
03401
03402 OPS ops = OPS_EMPTY;
03403 if (Expand_Special_And_Immed (tnr, tn0, const_val, &ops)) {
03404 if (EBO_Trace_Optimization) fprintf(TFile,"replace and with bit move\n");
03405 Set_OP_opnd(OPS_first(&ops), OP_PREDICATE_OPND, OP_opnd(op,OP_PREDICATE_OPND));
03406 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops), opnd_tninfo[OP_PREDICATE_OPND],
03407 NULL, opnd_tninfo[l0_opnd1_idx]);
03408 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
03409 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
03410 return TRUE;
03411 }
03412 }
03413 }
03414
03415 if (opcode == TOP_andcm) {
03416 if (ISA_LC_Value_In_Class (~const_val, LC_i8)) {
03417 OP *new_op;
03418 if (EBO_Trace_Optimization) fprintf(TFile,"replace and with complement and_i\n");
03419 new_op = Mk_OP(TOP_and_i, tnr, OP_opnd(op,OP_PREDICATE_OPND),
03420 Gen_Literal_TN(~const_val, TN_size(tn0)), tn0);
03421 OP_srcpos(new_op) = OP_srcpos(op);
03422 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND], NULL, opnd_tninfo[l0_opnd1_idx]);
03423 BB_Insert_Op_After(OP_bb(op), op, new_op);
03424 return TRUE;
03425 } else if (!EBO_in_loop) {
03426
03427
03428
03429 OPS ops = OPS_EMPTY;
03430 if (Expand_Special_And_Immed (tnr, tn0, ~const_val, &ops)) {
03431 if (EBO_Trace_Optimization) fprintf(TFile,"replace andcm with bit move\n");
03432 Set_OP_opnd(OPS_first(&ops), OP_PREDICATE_OPND, OP_opnd(op,OP_PREDICATE_OPND));
03433 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
03434 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
03435 return TRUE;
03436 }
03437 }
03438 }
03439
03440 if ((opcode == TOP_or) &&
03441 (ISA_LC_Value_In_Class (const_val, LC_i8))) {
03442 OP *new_op;
03443 if (EBO_Trace_Optimization) fprintf(TFile,"replace or with or_i\n");
03444 new_op = Mk_OP(TOP_or_i, tnr, OP_opnd(op,OP_PREDICATE_OPND),
03445 Gen_Literal_TN(const_val, TN_size(tn0)), tn0);
03446 OP_srcpos(new_op) = OP_srcpos(op);
03447 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND], NULL, opnd_tninfo[l0_opnd1_idx]);
03448 BB_Insert_Op_After(OP_bb(op), op, new_op);
03449 return TRUE;
03450 }
03451
03452 if ((opcode == TOP_xor) &&
03453 (ISA_LC_Value_In_Class (const_val, LC_i8))) {
03454 OP *new_op;
03455 if (EBO_Trace_Optimization) fprintf(TFile,"replace xor with xor_i\n");
03456 new_op = Mk_OP(TOP_xor_i, tnr, OP_opnd(op,OP_PREDICATE_OPND),
03457 Gen_Literal_TN(const_val, TN_size(tn0)), tn0);
03458 OP_srcpos(new_op) = OP_srcpos(op);
03459 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND], NULL, opnd_tninfo[l0_opnd1_idx]);
03460 BB_Insert_Op_After(OP_bb(op), op, new_op);
03461 return TRUE;
03462 }
03463
03464 if ((TOP_shl == opcode) && (const_val <= 63)) {
03465 if (EBO_Trace_Optimization) fprintf(TFile,"Convert shl to shl_i\n");
03466 OP *new_op;
03467 new_op = Mk_OP(TOP_shl_i, tnr, OP_opnd(op,OP_PREDICATE_OPND), tn0,
03468 Gen_Literal_TN(const_val, TN_size(tn0)));
03469 OP_srcpos(new_op) = OP_srcpos(op);
03470 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND], opnd_tninfo[l0_opnd1_idx], NULL);
03471 BB_Insert_Op_After(bb, op, new_op);
03472 return TRUE;
03473 }
03474
03475 if ((TOP_shr == opcode) && (const_val <= 63)) {
03476 if (EBO_Trace_Optimization) fprintf(TFile,"Convert shr to shr_i\n");
03477 OP *new_op;
03478 new_op = Mk_OP(TOP_shr_i, tnr, OP_opnd(op,OP_PREDICATE_OPND), tn0,
03479 Gen_Literal_TN(const_val, TN_size(tn0)));
03480 OP_srcpos(new_op) = OP_srcpos(op);
03481 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND], opnd_tninfo[l0_opnd1_idx], NULL);
03482 BB_Insert_Op_After(bb, op, new_op);
03483 return TRUE;
03484 }
03485
03486 if ((TOP_shr_u == opcode) && (const_val <= 63)) {
03487 if (EBO_Trace_Optimization) fprintf(TFile,"Convert shr_u to shr_i_u\n");
03488 OP *new_op;
03489 new_op = Mk_OP(TOP_shr_i_u, tnr, OP_opnd(op,OP_PREDICATE_OPND), tn0,
03490 Gen_Literal_TN(const_val, TN_size(tn0)));
03491 OP_srcpos(new_op) = OP_srcpos(op);
03492 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND], opnd_tninfo[l0_opnd1_idx], NULL);
03493 BB_Insert_Op_After(bb, op, new_op);
03494 return TRUE;
03495 }
03496
03497 if (OP_icmp(op)) {
03498 INT64 new_const_val = const_val;
03499 TOP new_opcode = Immediate_Compare(Reverse_Compare(opcode));
03500 if (new_opcode == TOP_UNDEFINED) return FALSE;
03501 if (TOP_Can_Have_Immediate(new_const_val, new_opcode)) {
03502
03503 OPS ops = OPS_EMPTY;
03504 TN *r1 = OP_result(op,0);
03505 TN *r2 = OP_result(op,1);
03506 Build_OP (new_opcode, r1, r2, OP_opnd(op,OP_PREDICATE_OPND),
03507 Gen_Literal_TN(new_const_val, TN_size(tn0)), tn0, &ops);
03508 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops), opnd_tninfo[OP_PREDICATE_OPND],
03509 NULL, opnd_tninfo[l0_opnd1_idx]);
03510 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
03511 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
03512 if (EBO_Trace_Optimization) fprintf(TFile,"reverse operands and replace cmp with cmp_i\n");
03513 return TRUE;
03514 }
03515 }
03516
03517
03518
03519 tninfo = opnd_tninfo[l0_opnd1_idx];
03520 if (tninfo == NULL) return FALSE;
03521 pred_op = tninfo->in_op;
03522 if (pred_op == NULL) return FALSE;
03523 pred_opcode = OP_code(pred_op);
03524 pred_opinfo = locate_opinfo_entry (tninfo);
03525 if (pred_opinfo == NULL) return FALSE;
03526
03527
03528 if (OP_load(pred_op)) {
03529 if (OP_iand(op)) {
03530 if (((pred_opcode == TOP_ld1) &&
03531 (const_val == (~((~0) << 8)))) ||
03532 ((pred_opcode == TOP_ld2) &&
03533 (const_val == (~((~0) << 16))))) {
03534
03535 OPS ops = OPS_EMPTY;
03536 if (EBO_Trace_Optimization) fprintf(TFile,"no need to mask after load\n");
03537 EBO_Exp_COPY((OP_has_predicate(op)?OP_opnd(op,OP_PREDICATE_OPND):NULL),
03538 tnr, tn0, &ops);
03539 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops),
03540 OP_has_predicate(op)?opnd_tninfo[OP_PREDICATE_OPND]:NULL,
03541 opnd_tninfo[l0_opnd1_idx]);
03542 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
03543 BB_Insert_Ops(bb, op, &ops, FALSE);
03544 return TRUE;
03545 }
03546 }
03547 return FALSE;
03548 }
03549
03550
03551
03552 if (TOP_Find_Operand_Use(OP_code(pred_op),OU_opnd2) >= 0) {
03553 TOP pred_opcode = OP_code(pred_op);
03554 INT ptn0_idx = TOP_Find_Operand_Use(pred_opcode,OU_opnd1);
03555 INT ptn1_idx = TOP_Find_Operand_Use(pred_opcode,OU_opnd2);
03556 TN *ptn0 = OP_opnd(pred_op, ptn0_idx);
03557 TN *ptn1 = OP_opnd(pred_op, ptn1_idx);
03558 EBO_TN_INFO *ptn0_tninfo;
03559 EBO_TN_INFO *ptn1_tninfo;
03560 INT64 pred_val = 0;
03561
03562 OP *new_op;
03563 TOP new_opcode;
03564 UINT64 new_const_val;
03565
03566 ptn0_tninfo = pred_opinfo->actual_opnd[ptn0_idx];
03567 ptn1_tninfo = pred_opinfo->actual_opnd[ptn1_idx];
03568
03569
03570 if (!(TN_Is_Constant(ptn0) || EBO_tn_available (bb, ptn0_tninfo)) ||
03571 !(TN_Is_Constant(ptn1) || EBO_tn_available (bb, ptn1_tninfo))) return FALSE;
03572 if (pred_opcode == TOP_spadjust) return FALSE;
03573
03574 if (TN_Is_Constant(ptn1) && !TN_is_symbol(ptn1)) {
03575 } else if (TN_Is_Constant(ptn0) && !TN_is_symbol(ptn0) &&
03576 (OP_iadd(pred_op) || OP_ior(pred_op) || OP_iand(pred_op))) {
03577 TN *s = ptn0;
03578 ptn0 = ptn1;
03579 ptn0_tninfo = ptn1_tninfo;
03580 ptn1 = s;
03581 } else return FALSE;
03582
03583
03584 if (!EBO_tn_available (bb, ptn0_tninfo)) {
03585 return FALSE;
03586 }
03587
03588 pred_val = TN_Value(ptn1);
03589
03590
03591 if ((opcode == pred_opcode) &&
03592 ((opcode == TOP_shl) ||
03593 (opcode == TOP_shl_i) ||
03594 (opcode == TOP_shr_u) ||
03595 (opcode == TOP_shr_i_u))) {
03596 new_const_val = pred_val + const_val;
03597
03598 if (new_const_val <= 63) {
03599
03600 switch (opcode) {
03601 case TOP_shl:
03602 case TOP_shl_i: new_opcode = TOP_shl_i; break;
03603 case TOP_shr_u:
03604 case TOP_shr_i_u: new_opcode = TOP_shr_i_u; break;
03605 default: return FALSE;
03606 }
03607
03608 new_op = Mk_OP (new_opcode, tnr, OP_opnd(op,OP_PREDICATE_OPND),
03609 ptn0, Gen_Literal_TN(new_const_val, TN_size(tn0)));
03610 OP_srcpos(new_op) = OP_srcpos(op);
03611 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND], ptn0_tninfo, NULL);
03612 BB_Insert_Op_After(bb, op, new_op);
03613 if (EBO_Trace_Optimization) fprintf(TFile,"combine identical shifts\n");
03614 return TRUE;
03615 }
03616 }
03617
03618 if (pred_val == const_val) {
03619
03620
03621 if ((OP_iand(op) && OP_iand(pred_op) && (const_val != ~0)) ||
03622 (OP_ior(op) && OP_ior(pred_op) && (const_val != 0))) {
03623 OPS ops = OPS_EMPTY;
03624 if (EBO_Trace_Optimization) fprintf(TFile,"replace redundant and/or\n");
03625 EBO_Exp_COPY((OP_has_predicate(op)?OP_opnd(op,OP_PREDICATE_OPND):NULL),
03626 tnr, OP_result(pred_op, 0), &ops);
03627 if (EBO_in_loop) EBO_OPS_omega (&ops, OP_has_predicate(op)?opnd_tninfo[OP_PREDICATE_OPND]:NULL);
03628 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
03629 BB_Insert_Ops(bb, op, &ops, FALSE);
03630 return TRUE;
03631 }
03632
03633
03634 if ((OP_iadd(op) && OP_isub(pred_op)) ||
03635 (OP_isub(op) && OP_iadd(pred_op))) {
03636
03637 OPS ops = OPS_EMPTY;
03638 if (EBO_Trace_Optimization) fprintf(TFile,"replace complementary operations\n");
03639 EBO_Exp_COPY((OP_has_predicate(op)?OP_opnd(op,OP_PREDICATE_OPND):NULL),
03640 tnr, ptn0, &ops);
03641 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops), opnd_tninfo[OP_PREDICATE_OPND], ptn0_tninfo);
03642 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
03643 BB_Insert_Ops(bb, op, &ops, FALSE);
03644 return TRUE;
03645 }
03646
03647 }
03648
03649 }
03650
03651 return FALSE;
03652 }
03653
03654
03655
03656
03657
03658
03659
03660
03661 BOOL
03662 Resolve_Conditional_Branch (OP *op, TN **opnd_tn)
03663 {
03664 BB *bb = OP_bb(op);
03665 BB *fall_bb;
03666 BB *branch_bb;
03667
03668 if (BBlist_Len(BB_succs(bb)) != 2) return FALSE;
03669
03670 fall_bb = BB_next(bb);
03671 branch_bb = BBLIST_item(BB_succs(bb));
03672 if (branch_bb == fall_bb) {
03673 branch_bb = BBLIST_item(BBLIST_next(BB_succs(bb)));
03674 }
03675
03676 if ((OP_code(op) == TOP_br_cond) &&
03677 (TOP_Find_Operand_Use(OP_code(op),OU_target) >= 0) &&
03678 OP_has_predicate(op) &&
03679 ((OP_opnd (op, OP_PREDICATE_OPND) == True_TN) ||
03680 TN_Is_Constant(opnd_tn[OP_PREDICATE_OPND]))) {
03681
03682
03683 if(IPFEC_Enable_Region_Formation && RGN_Formed) {
03684 if((Home_Region(bb)->Region_Type() == LOOP) &&
03685 ((Home_Region(branch_bb) != Home_Region(bb))||
03686 (Home_Region(fall_bb) != Home_Region(bb)))) {
03687 DevWarn("Give up resolve conditional branch in order to maintain region for BB %d.",BB_id(bb));
03688
03689 return FALSE;
03690 }
03691 }
03692
03693 if (EBO_Trace_Optimization) {
03694 #pragma mips_frequency_hint NEVER
03695 INT i;
03696 INT opndnum = OP_opnds(op);
03697 fprintf(TFile, "%sin BB:%d Resolve conditional BR :- %s ",
03698 EBO_trace_pfx, BB_id(bb),TOP_Name(OP_code(op)));
03699 for (i = 0; i < opndnum; i++) {
03700 fprintf(TFile," ");
03701 Print_TN(opnd_tn[i],FALSE);
03702 }
03703 fprintf(TFile,"\n");
03704 }
03705
03706
03707 if (opnd_tn[OP_PREDICATE_OPND] == True_TN) {
03708
03709 OPS ops = OPS_EMPTY;
03710
03711 Build_OP (TOP_br, Gen_Enum_TN(ECV_ph_few), Gen_Enum_TN(ECV_dh),
03712 OP_opnd(op,TOP_Find_Operand_Use(OP_code(op),OU_target)), &ops);
03713 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
03714 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
03715
03716 if(RGN_Formed && IPFEC_Enable_Region_Formation){
03717 RGN_Unlink_Pred_Succ(bb,fall_bb);
03718 } else {
03719 Unlink_Pred_Succ (bb, fall_bb);
03720 }
03721
03722 Change_Succ_Prob (bb, branch_bb, 1.0);
03723
03724 return TRUE;;
03725 } else if (opnd_tn[OP_PREDICATE_OPND] == Zero_TN) {
03726
03727 if(RGN_Formed && IPFEC_Enable_Region_Formation){
03728 RGN_Unlink_Pred_Succ(bb,branch_bb);
03729 } else {
03730 Unlink_Pred_Succ (bb, branch_bb);
03731 }
03732 Change_Succ_Prob (bb, fall_bb, 1.0);
03733
03734 return TRUE;
03735 }
03736 }
03737
03738 return FALSE;
03739 }
03740
03741
03742
03743
03744
03745
03746
03747
03748
03749
03750 BOOL
03751 Fold_Constant_Expression (OP *op,
03752 TN **opnd_tn,
03753 EBO_TN_INFO **opnd_tninfo)
03754 {
03755 TOP opcode = OP_code(op);
03756
03757 TN *tnr = OP_result(op,0);
03758 TN *tn0 = NULL;
03759 TN *tn1 = NULL;
03760 UINT64 tn0_uval = 0;
03761 INT64 tn0_val = 0;
03762 UINT64 tn1_uval = 0;
03763 INT64 tn1_val = 0;
03764 INT64 result_val;
03765 ST *result_sym = NULL;
03766 INT32 result_relocs;
03767
03768 if (EBO_Trace_Execution) {
03769 #pragma mips_frequency_hint NEVER
03770 INT i;
03771 INT opndnum = OP_opnds(op);
03772 fprintf(TFile, "%sin BB:%d Constant OP :- %s ",
03773 EBO_trace_pfx, BB_id(OP_bb(op)),TOP_Name(opcode));
03774 for (i = 0; i < opndnum; i++) {
03775 fprintf(TFile," ");
03776 Print_TN(opnd_tn[i],TRUE);
03777 }
03778 fprintf(TFile,"\n");
03779 }
03780
03781 if (OP_has_predicate(op) &&
03782 (opnd_tn[OP_PREDICATE_OPND] == Zero_TN)) {
03783
03784 if (TOP_Is_Unconditional_Compare(opcode)) {
03785
03786 OPS ops = OPS_EMPTY;
03787 if (OP_result(op,0) != True_TN) {
03788 Build_OP (TOP_cmp_eq_unc, True_TN, OP_result(op,0), True_TN, Zero_TN, Zero_TN, &ops);
03789 }
03790 if (OP_result(op,1) != True_TN) {
03791 Build_OP (TOP_cmp_eq_unc, True_TN, OP_result(op,1), True_TN, Zero_TN, Zero_TN, &ops);
03792 }
03793
03794 if (OP_glue(op)) {
03795 OP *next_op = OPS_first(&ops);
03796 while (next_op != NULL) {
03797 Set_OP_glue(next_op);
03798 next_op = OP_next(next_op);
03799 }
03800 }
03801
03802 if (EBO_Trace_Optimization) {
03803 #pragma mips_frequency_hint NEVER
03804 fprintf(TFile, "%sin BB:%d Result of compare is FALSE for both ", EBO_trace_pfx,BB_id(OP_bb(op)));
03805 Print_TN(OP_result(op,0),FALSE); fprintf(TFile," and ");
03806 Print_TN(OP_result(op,1),FALSE); fprintf(TFile, "\n");
03807 }
03808
03809 if (OPS_length(&ops) != 0) {
03810 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
03811 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
03812 }
03813 return TRUE;
03814 }
03815
03816
03817 return (!OP_glue(op));
03818 }
03819
03820
03821 if ((TN_register_class(tnr) != ISA_REGISTER_CLASS_integer) &&
03822 (TN_register_class(tnr) != ISA_REGISTER_CLASS_predicate)) {
03823
03824 return FALSE;
03825 }
03826
03827 if ((opcode == TOP_sxt4) ||
03828 (opcode == TOP_sxt2) ||
03829 (opcode == TOP_sxt1)) {
03830 INT length = EBO_bit_length(op);
03831 tn0 = opnd_tn[1];
03832 if (TN_is_symbol(tn0)) {
03833
03834 return FALSE;
03835 }
03836 tn0_val = TN_Value (tn0);
03837 result_val = (tn0_val << (64-length)) >> (64-length);
03838 goto Constant_Created;
03839 }
03840
03841 if ((opcode == TOP_zxt4) ||
03842 (opcode == TOP_zxt2) ||
03843 (opcode == TOP_zxt1)) {
03844 INT length = EBO_bit_length(op);
03845 tn0 = opnd_tn[1];
03846 if (TN_is_symbol(tn0)) {
03847
03848 return FALSE;
03849 }
03850 tn0_uval = TN_Value (tn0);
03851 result_val = (tn0_uval << (64-length)) >> (64-length);
03852 goto Constant_Created;
03853 }
03854
03855 if (OP_opnds(op) <= 2) {
03856 return FALSE;
03857 }
03858
03859 tn0 = opnd_tn[1];
03860 tn1 = opnd_tn[2];
03861
03862 if (TN_is_symbol(tn0)) {
03863 if (TN_is_symbol(tn1)) {
03864
03865 return FALSE;
03866 }
03867 tn0_uval = TN_offset(tn0);
03868 tn0_val = TN_offset(tn0);
03869 result_sym = TN_var(tn0);
03870 result_relocs = TN_relocs(tn0);
03871 } else if (TN_is_symbol(tn1)) {
03872 if (OP_isub(op)) {
03873
03874 return FALSE;
03875 }
03876 tn1_uval = TN_offset(tn1);
03877 tn1_val = TN_offset(tn1);
03878 result_sym = TN_var(tn1);
03879 result_relocs = TN_relocs(tn1);
03880 } else {
03881 tn0_uval = TN_Value (tn0);
03882 tn0_val = TN_Value (tn0);
03883 tn1_uval = TN_Value (tn1);
03884 tn1_val = TN_Value (tn1);
03885 }
03886
03887 if ((TOP_add == opcode) || (TOP_adds == opcode) ||
03888 (TOP_addl == opcode) || (TOP_addp4 == opcode) ||
03889 (TOP_addp4_i == opcode)) {
03890 result_val = tn0_uval + tn1_uval;
03891 goto Constant_Created;
03892 }
03893
03894 if (TOP_add_1 == opcode) {
03895 result_val = tn0_uval + tn1_uval + 1;
03896 goto Constant_Created;
03897 }
03898
03899 if ((TOP_sub == opcode) || (TOP_sub_i == opcode)) {
03900 result_val = tn0_uval - tn1_uval;
03901 goto Constant_Created;
03902 }
03903
03904 if (TOP_sub_1 == opcode) {
03905 result_val = tn0_uval - tn1_uval - 1;
03906 goto Constant_Created;
03907 }
03908
03909 if (TN_is_symbol(tn0) || TN_is_symbol(tn1)) {
03910
03911 return FALSE;
03912 }
03913
03914 if ((TOP_and == opcode) || (TOP_and_i == opcode)) {
03915 result_val = tn0_uval & tn1_uval;
03916 goto Constant_Created;
03917 }
03918
03919 if ((TOP_andcm == opcode) || (TOP_andcm_i == opcode)) {
03920 result_val = tn0_uval & (~tn1_uval);
03921 goto Constant_Created;
03922 }
03923
03924 if ((TOP_or == opcode) || (TOP_or_i == opcode)) {
03925 result_val = tn0_uval | tn1_uval;
03926 goto Constant_Created;
03927 }
03928
03929 if ((TOP_xor == opcode) || (TOP_xor_i == opcode)) {
03930 result_val = tn0_uval ^ tn1_uval;
03931 goto Constant_Created;
03932 }
03933
03934 if (TOP_shl == opcode) {
03935 if ((tn1_val < 0) || (tn1_val > 63)) {
03936 result_val = 0;
03937 } else {
03938 result_val = tn0_val << tn1_val;
03939 }
03940 goto Constant_Created;
03941 }
03942
03943 if (TOP_shladd == opcode) {
03944 if ((tn1_val < 0) || (tn1_val > 63)) {
03945 result_val = TN_Value(opnd_tn[3]);
03946 } else {
03947 result_val = (tn0_val << tn1_val) + TN_Value(opnd_tn[3]);
03948 }
03949 goto Constant_Created;
03950 }
03951
03952 if (TOP_shr_u == opcode) {
03953 if ((tn1_val < 0) || (tn1_val > 63)) {
03954 result_val = 0;
03955 } else {
03956 result_val = tn0_uval >> tn1_val;
03957 }
03958 goto Constant_Created;
03959 }
03960
03961 if (TOP_shr == opcode) {
03962 if ((tn1_val < 0) || (tn1_val > 63)) tn1_val = 63;
03963 result_val = tn0_val >> tn1_val;
03964 goto Constant_Created;
03965 }
03966
03967 if (opcode == TOP_extr) {
03968 INT start = tn1_val;
03969 INT length = TN_Value(opnd_tn[3]);
03970 if ((length+start) > 64) return FALSE;
03971 result_val = (tn0_val << (64-(length+start))) >> (64-length);
03972 goto Constant_Created;
03973 }
03974
03975 if (opcode == TOP_extr_u) {
03976 INT start = tn1_val;
03977 INT length = TN_Value(opnd_tn[3]);
03978 if ((length+start) > 64) return FALSE;
03979 result_val = (tn0_uval << (64-(length+start))) >> (64-length);
03980 goto Constant_Created;
03981 }
03982
03983 if ((opcode == TOP_dep) || (opcode == TOP_dep_i)) {
03984 INT start = TN_Value(opnd_tn[3]);
03985 INT length = TN_Value(opnd_tn[4]);
03986 UINT64 mask = (~0);
03987 mask = mask << length;
03988 result_val = (tn1_uval & ~(~mask << start)) | ((tn0_uval & ~mask) << start);
03989 goto Constant_Created;
03990 }
03991
03992 if ((opcode == TOP_dep_z) || (opcode == TOP_dep_i_z)) {
03993 INT start = tn1_val;
03994 INT length = TN_Value(opnd_tn[3]);
03995 UINT64 mask = (~0);
03996 mask = mask << length;
03997 result_val = ((tn0_uval & ~mask) << start);
03998 goto Constant_Created;
03999 }
04000
04001 if (OP_select(op)) {
04002 return Constant_Operand0 (op, opnd_tn, opnd_tninfo);
04003 }
04004
04005 if (OP_icmp(op)) {
04006
04007 if (OP_opnd(op, OP_PREDICATE_OPND) != True_TN) return FALSE;
04008
04009 switch (opcode) {
04010 case TOP_cmp_eq:
04011 case TOP_cmp_i_eq:
04012 case TOP_cmp_eq_unc:
04013 case TOP_cmp_i_eq_unc:
04014 result_val = (tn0_val == tn1_val);
04015 break;
04016 case TOP_cmp4_eq:
04017 case TOP_cmp4_i_eq:
04018 case TOP_cmp4_eq_unc:
04019 case TOP_cmp4_i_eq_unc:
04020 result_val = (TRUNC_32(tn0_val) == TRUNC_32(tn1_val));
04021 break;
04022 case TOP_cmp_ne:
04023 case TOP_cmp_i_ne:
04024 case TOP_cmp_ne_unc:
04025 case TOP_cmp_i_ne_unc:
04026 result_val = (tn0_val != tn1_val);
04027 break;
04028 case TOP_cmp4_ne:
04029 case TOP_cmp4_i_ne:
04030 case TOP_cmp4_ne_unc:
04031 case TOP_cmp4_i_ne_unc:
04032 result_val = (TRUNC_32(tn0_val) != TRUNC_32(tn1_val));
04033 break;
04034 case TOP_cmp_lt:
04035 case TOP_cmp_i_lt:
04036 case TOP_cmp_lt_unc:
04037 case TOP_cmp_i_lt_unc:
04038 result_val = (tn0_val < tn1_val);
04039 break;
04040 case TOP_cmp4_lt:
04041 case TOP_cmp4_i_lt:
04042 case TOP_cmp4_lt_unc:
04043 case TOP_cmp4_i_lt_unc:
04044 result_val = (SEXT_32(tn0_val) < SEXT_32(tn1_val));
04045 break;
04046 case TOP_cmp_gt:
04047 case TOP_cmp_i_gt:
04048 case TOP_cmp_gt_unc:
04049 case TOP_cmp_i_gt_unc:
04050 result_val = (tn0_val > tn1_val);
04051 break;
04052 case TOP_cmp4_gt:
04053 case TOP_cmp4_i_gt:
04054 case TOP_cmp4_gt_unc:
04055 case TOP_cmp4_i_gt_unc:
04056 result_val = (SEXT_32(tn0_val) > SEXT_32(tn1_val));
04057 break;
04058 case TOP_cmp_le:
04059 case TOP_cmp_i_le:
04060 case TOP_cmp_le_unc:
04061 case TOP_cmp_i_le_unc:
04062 result_val = (tn0_val <= tn1_val);
04063 break;
04064 case TOP_cmp4_le:
04065 case TOP_cmp4_i_le:
04066 case TOP_cmp4_le_unc:
04067 case TOP_cmp4_i_le_unc:
04068 result_val = (SEXT_32(tn0_val) <= SEXT_32(tn1_val));
04069 break;
04070 case TOP_cmp_ge:
04071 case TOP_cmp_i_ge:
04072 case TOP_cmp_ge_unc:
04073 case TOP_cmp_i_ge_unc:
04074 result_val = (tn0_val >= tn1_val);
04075 break;
04076 case TOP_cmp4_ge:
04077 case TOP_cmp4_i_ge:
04078 case TOP_cmp4_ge_unc:
04079 case TOP_cmp4_i_ge_unc:
04080 result_val = (SEXT_32(tn0_val) >= SEXT_32(tn1_val));
04081 break;
04082 case TOP_cmp_ltu:
04083 case TOP_cmp_i_ltu:
04084 case TOP_cmp_ltu_unc:
04085 case TOP_cmp_i_ltu_unc:
04086 result_val = (tn0_uval < tn1_uval);
04087 break;
04088 case TOP_cmp4_ltu:
04089 case TOP_cmp4_i_ltu:
04090 case TOP_cmp4_ltu_unc:
04091 case TOP_cmp4_i_ltu_unc:
04092 result_val = (TRUNC_32(tn0_uval) < TRUNC_32(tn1_uval));
04093 break;
04094 case TOP_cmp_gtu:
04095 case TOP_cmp_i_gtu:
04096 case TOP_cmp_gtu_unc:
04097 case TOP_cmp_i_gtu_unc:
04098 result_val = (tn0_uval > tn1_uval);
04099 break;
04100 case TOP_cmp4_gtu:
04101 case TOP_cmp4_i_gtu:
04102 case TOP_cmp4_gtu_unc:
04103 case TOP_cmp4_i_gtu_unc:
04104 result_val = (TRUNC_32(tn0_uval) > TRUNC_32(tn1_uval));
04105 break;
04106 case TOP_cmp_leu:
04107 case TOP_cmp_i_leu:
04108 case TOP_cmp_leu_unc:
04109 case TOP_cmp_i_leu_unc:
04110 result_val = (tn0_uval <= tn1_uval);
04111 break;
04112 case TOP_cmp4_leu:
04113 case TOP_cmp4_i_leu:
04114 case TOP_cmp4_leu_unc:
04115 case TOP_cmp4_i_leu_unc:
04116 result_val = (TRUNC_32(tn0_uval) <= TRUNC_32(tn1_uval));
04117 break;
04118 case TOP_cmp_geu:
04119 case TOP_cmp_i_geu:
04120 case TOP_cmp_geu_unc:
04121 case TOP_cmp_i_geu_unc:
04122 result_val = (tn0_uval >= tn1_uval);
04123 break;
04124 case TOP_cmp4_geu:
04125 case TOP_cmp4_i_geu:
04126 case TOP_cmp4_geu_unc:
04127 case TOP_cmp4_i_geu_unc:
04128 result_val = (TRUNC_32(tn0_uval) >= TRUNC_32(tn1_uval));
04129 break;
04130
04131
04132 case TOP_cmp4_eq_and:
04133 case TOP_cmp4_eq_or:
04134 case TOP_cmp4_eq_or_andcm:
04135 case TOP_cmp4_ne_and:
04136 case TOP_cmp4_ne_or:
04137 case TOP_cmp4_ne_or_andcm:
04138 case TOP_cmp4_z1_lt_and:
04139 case TOP_cmp4_z1_lt_or:
04140 case TOP_cmp4_z1_lt_or_andcm:
04141 case TOP_cmp4_z1_le_and:
04142 case TOP_cmp4_z1_le_or:
04143 case TOP_cmp4_z1_le_or_andcm:
04144 case TOP_cmp4_z1_gt_and:
04145 case TOP_cmp4_z1_gt_or:
04146 case TOP_cmp4_z1_gt_or_andcm:
04147 case TOP_cmp4_z1_ge_and:
04148 case TOP_cmp4_z1_ge_or:
04149 case TOP_cmp4_z1_ge_or_andcm:
04150 case TOP_cmp4_i_eq_and:
04151 case TOP_cmp4_i_eq_or:
04152 case TOP_cmp4_i_eq_or_andcm:
04153 case TOP_cmp4_i_ne_and:
04154 case TOP_cmp4_i_ne_or:
04155 case TOP_cmp4_i_ne_or_andcm:
04156 case TOP_cmp4_eq_orcm:
04157 case TOP_cmp4_eq_andcm:
04158 case TOP_cmp4_eq_and_orcm:
04159 case TOP_cmp4_ne_orcm:
04160 case TOP_cmp4_ne_andcm:
04161 case TOP_cmp4_ne_and_orcm:
04162 case TOP_cmp4_z1_lt_orcm:
04163 case TOP_cmp4_z1_lt_andcm:
04164 case TOP_cmp4_z1_lt_and_orcm:
04165 case TOP_cmp4_z1_le_orcm:
04166 case TOP_cmp4_z1_le_andcm:
04167 case TOP_cmp4_z1_le_and_orcm:
04168 case TOP_cmp4_z1_gt_orcm:
04169 case TOP_cmp4_z1_gt_andcm:
04170 case TOP_cmp4_z1_gt_and_orcm:
04171 case TOP_cmp4_z1_ge_orcm:
04172 case TOP_cmp4_z1_ge_andcm:
04173 case TOP_cmp4_z1_ge_and_orcm:
04174 case TOP_cmp4_z2_lt_orcm:
04175 case TOP_cmp4_z2_lt_andcm:
04176 case TOP_cmp4_z2_lt_and_orcm:
04177 case TOP_cmp4_z2_le_orcm:
04178 case TOP_cmp4_z2_le_andcm:
04179 case TOP_cmp4_z2_le_and_orcm:
04180 case TOP_cmp4_z2_gt_orcm:
04181 case TOP_cmp4_z2_gt_andcm:
04182 case TOP_cmp4_z2_gt_and_orcm:
04183 case TOP_cmp4_z2_ge_orcm:
04184 case TOP_cmp4_z2_ge_andcm:
04185 case TOP_cmp4_z2_ge_and_orcm:
04186 case TOP_cmp4_z2_lt_and:
04187 case TOP_cmp4_z2_lt_or:
04188 case TOP_cmp4_z2_lt_or_andcm:
04189 case TOP_cmp4_z2_le_and:
04190 case TOP_cmp4_z2_le_or:
04191 case TOP_cmp4_z2_le_or_andcm:
04192 case TOP_cmp4_z2_gt_and:
04193 case TOP_cmp4_z2_gt_or:
04194 case TOP_cmp4_z2_gt_or_andcm:
04195 case TOP_cmp4_z2_ge_and:
04196 case TOP_cmp4_z2_ge_or:
04197 case TOP_cmp4_z2_ge_or_andcm:
04198 case TOP_cmp4_i_eq_orcm:
04199 case TOP_cmp4_i_eq_andcm:
04200 case TOP_cmp4_i_eq_and_orcm:
04201 case TOP_cmp4_i_ne_orcm:
04202 case TOP_cmp4_i_ne_andcm:
04203 case TOP_cmp4_i_ne_and_orcm:
04204 case TOP_cmp4_lt_and:
04205 case TOP_cmp4_lt_or:
04206 case TOP_cmp4_lt_or_andcm:
04207 case TOP_cmp4_le_and:
04208 case TOP_cmp4_le_or:
04209 case TOP_cmp4_le_or_andcm:
04210 case TOP_cmp4_gt_and:
04211 case TOP_cmp4_gt_or:
04212 case TOP_cmp4_gt_or_andcm:
04213 case TOP_cmp4_ge_and:
04214 case TOP_cmp4_ge_or:
04215 case TOP_cmp4_ge_or_andcm:
04216 case TOP_cmp4_lt_orcm:
04217 case TOP_cmp4_lt_andcm:
04218 case TOP_cmp4_lt_and_orcm:
04219 case TOP_cmp4_le_orcm:
04220 case TOP_cmp4_le_andcm:
04221 case TOP_cmp4_le_and_orcm:
04222 case TOP_cmp4_gt_orcm:
04223 case TOP_cmp4_gt_andcm:
04224 case TOP_cmp4_gt_and_orcm:
04225 case TOP_cmp4_ge_orcm:
04226 case TOP_cmp4_ge_andcm:
04227 case TOP_cmp4_ge_and_orcm:
04228
04229
04230 default:
04231 return FALSE;
04232 break;
04233 }
04234
04235 OPS ops = OPS_EMPTY;
04236 TN *result1 = (result_val == 0) ? OP_result(op,1) : OP_result(op,0);
04237 TN *result2 = (result_val == 0) ? OP_result(op,0) : OP_result(op,1);
04238 if (result1 != True_TN){
04239 Build_OP (TOP_Is_Unconditional_Compare(opcode) ? TOP_cmp_eq_unc : TOP_cmp_eq,
04240 result1, True_TN, OP_opnd(op, OP_PREDICATE_OPND), Zero_TN, Zero_TN, &ops);
04241 OP_srcpos(OPS_last(&ops)) = OP_srcpos(op);
04242 }
04243 if (result2 != True_TN){
04244 Build_OP (TOP_Is_Unconditional_Compare(opcode) ? TOP_cmp_eq_unc : TOP_cmp_eq,
04245 True_TN, result2, OP_opnd(op, OP_PREDICATE_OPND), Zero_TN, Zero_TN, &ops);
04246 OP_srcpos(OPS_last(&ops)) = OP_srcpos(op);
04247 }
04248
04249 if (EBO_Trace_Optimization) {
04250 #pragma mips_frequency_hint NEVER
04251 fprintf(TFile, "%sin BB:%d Result of compare is %s for ",
04252 EBO_trace_pfx, BB_id(OP_bb(op)),(result_val == 0) ? "FALSE" : "TRUE");
04253 Print_TN(OP_result(op,0),FALSE); fprintf(TFile," complement ");
04254 Print_TN(OP_result(op,1),FALSE); fprintf(TFile, "\n");
04255 }
04256
04257 if (EBO_in_loop) EBO_OPS_omega (&ops, opnd_tninfo[OP_PREDICATE_OPND]);
04258 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
04259 return TRUE;
04260 }
04261
04262 if ((opcode == TOP_tbit_z) ||
04263 (opcode == TOP_tbit_nz) ||
04264 (opcode == TOP_tbit_z_unc) ||
04265 (opcode == TOP_tbit_nz_unc)) {
04266 result_val = (tn0_uval >> tn1_val) & 1;
04267 result_val = ((opcode == TOP_tbit_z) || (opcode == TOP_tbit_z_unc)) ? !result_val : result_val;
04268 OPS ops = OPS_EMPTY;
04269 TN *result1 = (result_val == 0) ? OP_result(op,1) : OP_result(op,0);
04270 TN *result2 = (result_val == 0) ? OP_result(op,0) : OP_result(op,1);
04271 Build_OP (TOP_Is_Unconditional_Compare(opcode) ? TOP_cmp_eq_unc : TOP_cmp_eq,
04272 result1, True_TN, OP_opnd(op, OP_PREDICATE_OPND), Zero_TN, Zero_TN, &ops);
04273 OP_srcpos(OPS_last(&ops)) = OP_srcpos(op);
04274 Build_OP (TOP_Is_Unconditional_Compare(opcode) ? TOP_cmp_eq_unc : TOP_cmp_eq,
04275 True_TN, result2, OP_opnd(op, OP_PREDICATE_OPND), Zero_TN, Zero_TN, &ops);
04276 OP_srcpos(OPS_last(&ops)) = OP_srcpos(op);
04277
04278 if (EBO_Trace_Optimization) {
04279 #pragma mips_frequency_hint NEVER
04280 fprintf(TFile, "%sin BB:%d Result of tbit is %s for ",
04281 EBO_trace_pfx, BB_id(OP_bb(op)),(result_val == 0) ? "FALSE" : "TRUE");
04282 Print_TN(OP_result(op,0),FALSE); fprintf(TFile," complement ");
04283 Print_TN(OP_result(op,1),FALSE); fprintf(TFile, "\n");
04284 }
04285
04286 if (EBO_in_loop) EBO_OPS_omega (&ops, opnd_tninfo[OP_PREDICATE_OPND]);
04287 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
04288 return TRUE;
04289 }
04290
04291 return FALSE;
04292
04293 Constant_Created:
04294
04295 OPS ops = OPS_EMPTY;
04296 TN *tnc;
04297
04298 if (result_sym != NULL) {
04299 tnc = Gen_Symbol_TN(result_sym, result_val, result_relocs);
04300 }
04301 else {
04302 switch (TN_size(tnr)) {
04303 case 1:
04304 FmtAssert (!((tn0_uval & 0x1111111111111110LL == 0x0000000000000010LL) &&
04305 (tn1_uval & 0x1111111111111110LL == 0x0000000000000010LL) &&
04306 (result_val & 0x0000000000000100LL)),
04307 ("1-byte literal 0x%016llx is out-of-range", result_val));
04308 result_val &= 0x00000000000000ffLL;
04309 break;
04310 case 2:
04311 FmtAssert (!((tn0_uval & 0x1111111111111000LL == 0x0000000000001000LL) &&
04312 (tn1_uval & 0x1111111111111000LL == 0x0000000000001000LL) &&
04313 (result_val & 0x0000000000010000LL)),
04314 ("2-byte literal 0x%016llx is out-of-range", result_val));
04315 result_val &= 0x000000000000ffffLL;
04316 break;
04317 case 4:
04318 FmtAssert (!((tn0_uval & 0x1111111110000000LL == 0x0000000010000000LL) &&
04319 (tn1_uval & 0x1111111110000000LL == 0x0000000010000000LL) &&
04320 (result_val & 0x0000000100000000LL)),
04321 ("4-byte literal 0x%016llx is out-of-range", result_val));
04322 result_val &= 0x00000000ffffffffLL;
04323 break;
04324 case 8:
04325 break;
04326 default:
04327 FmtAssert(false, ("Invalid literal tn size: %d", TN_size(tnr)));
04328 }
04329
04330 tnc = Gen_Literal_TN(result_val, TN_size(tnr));
04331 }
04332 Expand_Immediate (tnr, tnc, OP_result_is_signed(op,0), &ops);
04333 if (OP_next(OPS_first(&ops)) != NULL) {
04334
04335 return FALSE;
04336 }
04337 if (OP_has_predicate(op)) {
04338 EBO_OPS_predicate (OP_opnd(op, OP_PREDICATE_OPND), &ops);
04339 }
04340 if (EBO_in_loop) EBO_OPS_omega (&ops, opnd_tninfo[OP_PREDICATE_OPND]);
04341 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
04342 if (opcode == OP_code(OPS_first(&ops))) {
04343 BOOL all_operands_are_the_same = TRUE;
04344 INT i;
04345 for (i = 0; i < OP_opnds(op); i++) {
04346 if (!TNs_Are_Equivalent(OP_opnd(op, i), OP_opnd(OPS_first(&ops), i))) {
04347 all_operands_are_the_same = FALSE;
04348 break;
04349 }
04350 }
04351 if (all_operands_are_the_same) {
04352
04353 return FALSE;
04354 }
04355 }
04356 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
04357
04358 if (EBO_Trace_Optimization) {
04359 #pragma mips_frequency_hint NEVER
04360 fprintf(TFile, "%sin BB:%d Redefine ",
04361 EBO_trace_pfx, BB_id(OP_bb(op)));
04362 Print_TN(tnr,TRUE);
04363 fprintf(TFile," with load of ");
04364 Print_TN(tnc,FALSE);
04365 fprintf(TFile, "\n");
04366 }
04367
04368 return TRUE;
04369 }
04370
04371
04372
04373
04374
04375
04376
04377 INT EBO_Copy_Operand (OP *op)
04378 {
04379 TOP opcode;
04380 INT opnd;
04381
04382 if (OP_copy(op)) {
04383 return OP_COPY_OPND;
04384 }
04385
04386 opnd = CGTARG_Copy_Operand(op);
04387 if (opnd >= 0) {
04388 return opnd;
04389 }
04390
04391 if (OP_iadd(op) || OP_ior(op) || OP_ixor(op)) {
04392 if (OP_code(op) == TOP_spadjust) {
04393 return -1;
04394 }
04395 if ((TN_is_register(OP_opnd(op,1)) &&
04396 TN_register_and_class(OP_opnd(op,1)) == CLASS_AND_REG_zero) ||
04397 ((TN_has_value(OP_opnd(op,1)) && TN_value(OP_opnd(op,1)) == 0))) {
04398 return 2;
04399 }
04400 if ((TN_is_register(OP_opnd(op,2)) &&
04401 TN_register_and_class(OP_opnd(op,2)) == CLASS_AND_REG_zero) ||
04402 ((TN_has_value(OP_opnd(op,2)) && TN_value(OP_opnd(op,2)) == 0))) {
04403 return 1;
04404 }
04405 }
04406
04407 if (OP_iand(op)) {
04408 if ((TN_has_value(OP_opnd(op,1)) && TN_value(OP_opnd(op,1)) == ~0)) {
04409 return 2;
04410 }
04411 if ((TN_has_value(OP_opnd(op,2)) && TN_value(OP_opnd(op,2)) == ~0)) {
04412 return 1;
04413 }
04414 }
04415
04416 opcode = OP_code(op);
04417 if ((opcode == TOP_mov) ||
04418 (opcode == TOP_mov_i) ||
04419 (opcode == TOP_movl) ||
04420 (opcode == TOP_mov_f)) {
04421 return 1;
04422 }
04423 if ((opcode == TOP_mov_t_br) ||
04424 (opcode == TOP_mov_f_br)) {
04425 return 1;
04426 }
04427 if ((opcode == TOP_mov_t_ar_r) ||
04428 (opcode == TOP_mov_t_ar_i) ||
04429 (opcode == TOP_mov_f_ar) ||
04430 (opcode == TOP_mov_f_ar_i) ||
04431 (opcode == TOP_mov_t_ar_r_i) ||
04432 (opcode == TOP_mov_t_ar_i_i) ||
04433 (opcode == TOP_mov_f_ar_m) ||
04434 (opcode == TOP_mov_t_ar_r_m) ||
04435 (opcode == TOP_mov_t_ar_i_m)) {
04436 return 1;
04437 }
04438 if ((opcode == TOP_setf_s) || (opcode == TOP_setf_d) ||
04439 (opcode == TOP_getf_s) || (opcode == TOP_getf_d)) {
04440 return 1;
04441 }
04442
04443 if (((opcode == TOP_cmp_eq_unc) ||
04444 (opcode == TOP_cmp_eq && OP_opnd(op,OP_PREDICATE_OPND) == True_TN)) &&
04445 (OP_opnd(op,1) == Zero_TN) &&
04446 (OP_opnd(op,2) == Zero_TN)) {
04447 return 0;
04448 }
04449
04450 return -1;
04451 }
04452
04453
04454
04455
04456
04457
04458
04459
04460
04461
04462
04463
04464
04465
04466
04467
04468
04469 static
04470 BOOL
04471 fadd_fmult (OP *op, EBO_TN_INFO **opnd_tninfo)
04472 {
04473
04474 BB *bb = OP_bb(op);
04475 OP *l1_op0 = op;
04476 TN *l1_tn0;
04477
04478
04479 OP *l2_op0;
04480 TN *l2_tn0;
04481 EBO_TN_INFO *l2_tninfo0;
04482 OP *l2_op1;
04483 TN *l2_tn1;
04484 EBO_TN_INFO *l2_tninfo1;
04485 EBO_OP_INFO *l2_opinfo1;
04486
04487
04488 TN *l3_tn1;
04489 EBO_TN_INFO *l3_tninfo1;
04490 TN *l3_tn2;
04491 EBO_TN_INFO *l3_tninfo2;
04492
04493 TOP new_opcode = TOP_UNDEFINED;
04494 OP *new_fmadd;
04495
04496 if (!Madd_Allowed) return FALSE;
04497 if (!CG_create_madds) return FALSE;
04498
04499 if (OP_fadd(l1_op0) || OP_fsub(l1_op0)) {
04500 TOP l1_opcode = OP_code(l1_op0);
04501 INT l2_opnd1_idx = TOP_Find_Operand_Use(l1_opcode,OU_opnd1);
04502 INT l2_opnd2_idx = TOP_Find_Operand_Use(l1_opcode,OU_opnd2);
04503
04504 l1_tn0 = OP_result(l1_op0,0);
04505 l2_tn0 = OP_opnd(op,l2_opnd1_idx);
04506 l2_tn1 = OP_opnd(op,l2_opnd2_idx);
04507
04508 l2_tninfo0 = opnd_tninfo[l2_opnd1_idx];
04509 l2_tninfo1 = opnd_tninfo[l2_opnd2_idx];
04510 if ((l2_tninfo0 == NULL) ||
04511 (l2_tninfo1 == NULL)) {
04512 return FALSE;
04513 }
04514
04515
04516 l2_op0 = l2_tninfo0->in_op;
04517 l2_op1 = l2_tninfo1->in_op;
04518
04519
04520
04521
04522
04523
04524 if ((l2_op1 == NULL) || !OP_fmul(l2_op1)) {
04525
04526 if ((l2_op0 == NULL) || !OP_fmul(l2_op0)) {
04527 return FALSE;
04528 }
04529
04530
04531 l2_tn0 = l2_tn1;
04532 l2_tn1 = OP_opnd(op,l2_opnd1_idx);
04533 l2_tninfo0 = l2_tninfo1;
04534 l2_tninfo1 = opnd_tninfo[l2_opnd1_idx];
04535 l2_op0 = l2_op1;
04536 l2_op1 = l2_tninfo1->in_op;
04537 }
04538
04539
04540 l2_opinfo1 = locate_opinfo_entry (l2_tninfo1);
04541 if ((l2_opinfo1 == NULL) ||
04542 (l2_opinfo1->in_op == NULL)) {
04543 return FALSE;
04544 }
04545
04546 TOP l2_opcode = OP_code(l2_op1);
04547 INT l3_opnd1_idx = TOP_Find_Operand_Use(l2_opcode,OU_opnd1);
04548 INT l3_opnd2_idx = TOP_Find_Operand_Use(l2_opcode,OU_opnd2);
04549
04550 l3_tn1 = OP_opnd(l2_op1, l3_opnd1_idx);
04551 l3_tn2 = OP_opnd(l2_op1, l3_opnd2_idx);
04552 l3_tninfo1 = l2_opinfo1->actual_opnd[l3_opnd1_idx];
04553 l3_tninfo2 = l2_opinfo1->actual_opnd[l3_opnd2_idx];
04554 if ((l3_tn1 == NULL) || TN_Is_Constant(l3_tn1) ||
04555 (l3_tn2 == NULL) || TN_Is_Constant(l3_tn2) ||
04556 (l3_tninfo1 == NULL) || (l3_tninfo2 == NULL)) {
04557 return FALSE;
04558 }
04559
04560
04561 if (!EBO_tn_available (bb, l3_tninfo1) ||
04562 !EBO_tn_available (bb, l3_tninfo2)) {
04563 return FALSE;
04564 }
04565
04566
04567 if (OP_result_size(op,0) != OP_result_size(l2_op1,0)) {
04568 return FALSE;
04569 }
04570
04571
04572
04573
04574
04575
04576 if (OP_fadd(l1_op0)) {
04577
04578
04579
04580
04581 switch (l2_opcode) {
04582 case TOP_fpmpy: new_opcode = TOP_fpma; break;
04583 case TOP_fmpy: new_opcode = TOP_fma; break;
04584 case TOP_fmpy_s: new_opcode = TOP_fma_s; break;
04585 case TOP_fmpy_d: new_opcode = TOP_fma_d; break;
04586 case TOP_fpnmpy: new_opcode = TOP_fpnma; break;
04587 case TOP_fnmpy: new_opcode = TOP_fnma; break;
04588 case TOP_fnmpy_s: new_opcode = TOP_fnma_s; break;
04589 case TOP_fnmpy_d: new_opcode = TOP_fnma_d; break;
04590 default: return FALSE;
04591 }
04592
04593 } else if (OP_fsub(l1_op0) && (l2_tn1 == OP_opnd(op,l2_opnd1_idx))) {
04594
04595
04596
04597
04598 switch (l2_opcode) {
04599 case TOP_fpmpy: new_opcode = TOP_fpms; break;
04600 case TOP_fmpy: new_opcode = TOP_fms; break;
04601 case TOP_fmpy_s: new_opcode = TOP_fms_s; break;
04602 case TOP_fmpy_d: new_opcode = TOP_fms_d; break;
04603 default: return FALSE;
04604 }
04605
04606 } else {
04607
04608
04609
04610 switch (l2_opcode) {
04611 case TOP_fpmpy: new_opcode = TOP_fpnma; break;
04612 case TOP_fmpy: new_opcode = TOP_fnma; break;
04613 case TOP_fmpy_s: new_opcode = TOP_fnma_s; break;
04614 case TOP_fmpy_d: new_opcode = TOP_fnma_d; break;
04615 case TOP_fpnmpy: new_opcode = TOP_fpma; break;
04616 case TOP_fnmpy: new_opcode = TOP_fma; break;
04617 case TOP_fnmpy_s: new_opcode = TOP_fma_s; break;
04618 case TOP_fnmpy_d: new_opcode = TOP_fma_d; break;
04619 default: return FALSE;
04620 }
04621
04622 }
04623
04624 new_fmadd = Mk_OP (new_opcode, l1_tn0, OP_opnd(op,OP_PREDICATE_OPND),
04625 Gen_Enum_TN(ECV_sf_s0), l3_tn1, l3_tn2, l2_tn0);
04626 OP_srcpos(new_fmadd) = OP_srcpos(l1_op0);
04627 if (EBO_in_loop) EBO_Set_OP_omega ( new_fmadd, opnd_tninfo[OP_PREDICATE_OPND],
04628 NULL, l3_tninfo1, l3_tninfo2, l2_tninfo0);
04629 BB_Insert_Op_After(bb, op, new_fmadd);
04630
04631 if (EBO_Trace_Optimization) fprintf(TFile,"%s(%s) was converted to a madd: %s.\n",
04632 TOP_Name(OP_code(op)),TOP_Name(OP_code(l2_op1)),TOP_Name(OP_code(new_fmadd)));
04633 return TRUE;
04634 }
04635
04636 return FALSE;
04637 }
04638
04639
04640
04641
04642
04643
04644
04645
04646
04647
04648
04649
04650
04651
04652
04653
04654
04655
04656
04657
04658
04659
04660 static
04661 BOOL
04662 fneg_sequence (OP *op, TN **opnd_tn, EBO_TN_INFO **opnd_tninfo)
04663 {
04664
04665 TOP opcode = OP_code(op);
04666 BB *bb = OP_bb(op);
04667 OP *l1_op0 = op;
04668 TN *l1_tn0;
04669 INT op1_idx = TOP_Find_Operand_Use(opcode,OU_opnd1);
04670
04671
04672 TOP l2_opcode;
04673 OP *l2_op0;
04674 EBO_TN_INFO *l2_tninfo0;
04675 EBO_OP_INFO *l2_opinfo0;
04676
04677
04678 TN *l3_tn0;
04679 EBO_TN_INFO *l3_tninfo0;
04680 TN *l3_tn1;
04681 EBO_TN_INFO *l3_tninfo1;
04682 TN *l3_tn2;
04683 EBO_TN_INFO *l3_tninfo2;
04684
04685 TOP new_opcode = TOP_UNDEFINED;
04686 OP *new_op;
04687
04688 if ((opcode != TOP_fneg) &&
04689 (opcode != TOP_fpneg)) {
04690 return FALSE;
04691 }
04692
04693
04694
04695
04696
04697
04698
04699 TN *predicate_tn = opnd_tn[OP_PREDICATE_OPND];
04700 EBO_TN_INFO *predicate_tninfo = opnd_tninfo[OP_PREDICATE_OPND];
04701 if ((opcode == TOP_fneg) &&
04702 (predicate_tninfo != NULL) &&
04703 (predicate_tninfo->in_op != NULL) &&
04704 (!TN_Is_Constant(predicate_tn))) {
04705
04706 TN *tnr = OP_result(op,0);
04707 EBO_TN_INFO *previous_tninfo = get_tn_info(tnr);
04708 EBO_OP_INFO *previous_opinfo = NULL;
04709 EBO_TN_INFO *previous_op0_tninfo = NULL;
04710 if ((previous_tninfo != NULL) &&
04711 (previous_tninfo->reference_count == 0) &&
04712 (previous_tninfo->predicate_tninfo != NULL)) {
04713 previous_opinfo = locate_opinfo_entry (previous_tninfo);
04714 if (previous_opinfo != NULL) {
04715 previous_op0_tninfo = previous_opinfo->optimal_opnd[op1_idx];
04716 }
04717 }
04718 if ((previous_op0_tninfo != NULL) &&
04719 (opnd_tn[op1_idx] == previous_op0_tninfo->local_tn) &&
04720 EBO_predicate_complements (predicate_tn, predicate_tninfo,
04721 previous_tninfo->predicate_tninfo->local_tn, previous_tninfo->predicate_tninfo)) {
04722 OP *predicate_op = predicate_tninfo->in_op;
04723 TOP predicate_opcode = OP_code(predicate_op);
04724 EBO_OP_INFO *predicate_opinfo = locate_opinfo_entry (predicate_tninfo);
04725 if ((predicate_opinfo != NULL) &&
04726 (predicate_opinfo->in_op != NULL) &&
04727 (((predicate_opcode == TOP_fcmp_gt_unc) || (predicate_opcode == TOP_fcmp_ge_unc)) &&
04728 (predicate_opinfo->actual_rslt[1] == predicate_tninfo) &&
04729 (OP_opnd(predicate_op, TOP_Find_Operand_Use(predicate_opcode,OU_opnd2)) == FZero_TN) &&
04730 (predicate_opinfo->actual_opnd[TOP_Find_Operand_Use(predicate_opcode,OU_opnd1)] == opnd_tninfo[op1_idx]))) {
04731 if (EBO_Trace_Optimization) fprintf(TFile,"simplify fneg(fcmp()) operation.\n");
04732 new_opcode = TOP_fmerge_s;
04733 new_op = Mk_OP (new_opcode, tnr,
04734 OP_opnd(predicate_op,OP_PREDICATE_OPND), FZero_TN, OP_opnd(op,1));
04735 OP_srcpos(new_op) = OP_srcpos(op);
04736 if (EBO_in_loop) EBO_Set_OP_omega ( new_op,
04737 predicate_opinfo->actual_opnd[OP_PREDICATE_OPND],
04738 opnd_tninfo[op1_idx]);
04739 BB_Insert_Op_After(bb, op, new_op);
04740
04741
04742 remove_op (previous_opinfo);
04743 OP_Change_To_Noop(previous_opinfo->in_op);
04744 previous_opinfo->in_op = NULL;
04745 previous_opinfo->in_bb = NULL;
04746 return TRUE;
04747 }
04748 }
04749 }
04750
04751 l1_tn0 = OP_result(l1_op0,0);
04752 l2_tninfo0 = opnd_tninfo[op1_idx];
04753 if ((l2_tninfo0 == NULL) ||
04754 (l2_tninfo0->in_op == NULL)) {
04755 return FALSE;
04756 }
04757 l2_op0 = l2_tninfo0->in_op;
04758
04759
04760 l2_opinfo0 = locate_opinfo_entry (l2_tninfo0);
04761 if ((l2_opinfo0 == NULL) ||
04762 (l2_opinfo0->in_op == NULL)) {
04763 return FALSE;
04764 }
04765
04766 l2_opcode = OP_code(l2_op0);
04767
04768 INT l2_opnd1_idx = TOP_Find_Operand_Use(l2_opcode,OU_opnd1);
04769 INT l2_opnd2_idx = TOP_Find_Operand_Use(l2_opcode,OU_opnd2);
04770 INT l2_opnd3_idx = TOP_Find_Operand_Use(l2_opcode,OU_maddend);
04771 if (l2_opnd1_idx >= 0) {
04772 l3_tn0 = OP_opnd(l2_op0, l2_opnd1_idx);
04773 l3_tninfo0 = l2_opinfo0->actual_opnd[l2_opnd1_idx];
04774 if ((l3_tn0 == NULL) || TN_Is_Constant(l3_tn0) ||
04775 !EBO_tn_available (bb, l3_tninfo0)) return FALSE;
04776
04777 if (l2_opnd2_idx >= 0) {
04778 l3_tn1 = OP_opnd(l2_op0, l2_opnd2_idx);
04779 l3_tninfo1 = l2_opinfo0->actual_opnd[l2_opnd2_idx];
04780 if ((l3_tn1 == NULL) || TN_Is_Constant(l3_tn1) ||
04781 !EBO_tn_available (bb, l3_tninfo1)) return FALSE;
04782
04783 if (l2_opnd3_idx >= 0) {
04784 l3_tn2 = OP_opnd(l2_op0, l2_opnd3_idx);
04785 l3_tninfo2 = l2_opinfo0->actual_opnd[l2_opnd3_idx];
04786 if ((l3_tn2 == NULL) || TN_Is_Constant(l3_tn2) ||
04787 !EBO_tn_available (bb, l3_tninfo2)) return FALSE;
04788 }
04789 }
04790 }
04791
04792
04793
04794 if (l2_opnd3_idx <= 0) {
04795
04796
04797 switch (l2_opcode) {
04798 case TOP_fneg:
04799 case TOP_fpneg: {
04800 OPS ops = OPS_EMPTY;
04801 if (EBO_Trace_Optimization) fprintf(TFile,"simplify fneg(fneg()) operation.\n");
04802 Exp_COPY(l1_tn0, l3_tn0, &ops);
04803 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
04804 if (EBO_in_loop) EBO_Set_OP_omega ( OPS_last(&ops), opnd_tninfo[OP_PREDICATE_OPND], l3_tninfo0);
04805 BB_Insert_Ops(bb, op, &ops, FALSE);
04806 return TRUE;
04807 }
04808 case TOP_fsub:
04809 case TOP_fsub_s:
04810 case TOP_fsub_d: {
04811 if (EBO_Trace_Optimization) fprintf(TFile,"simplify fneg(fsub()) operation.\n");
04812 new_op = Mk_OP (l2_opcode, l1_tn0, OP_opnd(op,OP_PREDICATE_OPND),
04813 Gen_Enum_TN(ECV_sf_s0), l3_tn1, l3_tn0);
04814 OP_srcpos(new_op) = OP_srcpos(op);
04815 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND],
04816 NULL, l3_tninfo1, l3_tninfo0);
04817 BB_Insert_Op_After(bb, op, new_op);
04818 return TRUE;
04819 }
04820 case TOP_fpmpy: new_opcode = TOP_fpnmpy; break;
04821 case TOP_fmpy: new_opcode = TOP_fnmpy; break;
04822 case TOP_fmpy_s: new_opcode = TOP_fnmpy_s; break;
04823 case TOP_fmpy_d: new_opcode = TOP_fnmpy_d; break;
04824 case TOP_fpnmpy: new_opcode = TOP_fpmpy; break;
04825 case TOP_fnmpy: new_opcode = TOP_fmpy; break;
04826 case TOP_fnmpy_s: new_opcode = TOP_fmpy_s; break;
04827 case TOP_fnmpy_d: new_opcode = TOP_fmpy_d; break;
04828 default: return FALSE;
04829 }
04830
04831 if (EBO_Trace_Optimization) fprintf(TFile,"simplify fneg(fmpy()) operation.\n");
04832 new_op = Mk_OP (new_opcode, l1_tn0, OP_opnd(op,OP_PREDICATE_OPND),
04833 Gen_Enum_TN(ECV_sf_s0), l3_tn0, l3_tn1);
04834 OP_srcpos(new_op) = OP_srcpos(op);
04835 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND],
04836 NULL, l3_tninfo0, l3_tninfo1);
04837 BB_Insert_Op_After(bb, op, new_op);
04838 return TRUE;
04839 } else {
04840
04841
04842
04843 return FALSE;
04844 }
04845
04846 return FALSE;
04847 }
04848
04849
04850
04851
04852
04853
04854
04855
04856
04857
04858
04859
04860
04861 static
04862 BOOL
04863 shl_add_sequence (OP *op,
04864 TN **opnd_tn,
04865 EBO_TN_INFO **opnd_tninfo)
04866 {
04867
04868 TOP opcode = OP_code(op);
04869 if (opcode != TOP_add) return FALSE;
04870
04871
04872 BB *bb = OP_bb(op);
04873 OP *l1_op0 = op;
04874 TN *l1_tn0 = OP_result(l1_op0,0);
04875
04876
04877 OP *l2_op0;
04878 TN *l2_tn1 = OP_opnd(op,2);
04879 EBO_TN_INFO *l2_tninfo0 = opnd_tninfo[1];
04880 EBO_TN_INFO *l2_tninfo1 = opnd_tninfo[2];
04881 EBO_OP_INFO *l2_opinfo0;
04882
04883
04884 TN *l3_tn0;
04885 TN *l3_tn1;
04886 EBO_TN_INFO *l3_tninfo0;
04887 INT64 l3_val1;
04888
04889
04890
04891
04892 if ((l2_tninfo0 == NULL) ||
04893 (l2_tninfo0->in_op == NULL) ||
04894 ((OP_code(l2_tninfo0->in_op) != TOP_shl_i) &&
04895 ((OP_code(l2_tninfo0->in_op) != TOP_shladd) ||
04896 (OP_opnd(l2_tninfo0->in_op,3) != Zero_TN)))) {
04897
04898 l2_tn1 = OP_opnd(op,1);
04899 l2_tninfo0 = l2_tninfo1;
04900 l2_tninfo1 = opnd_tninfo[1];
04901
04902 if ((l2_tninfo0 == NULL) ||
04903 (l2_tninfo0->in_op == NULL) ||
04904 ((OP_code(l2_tninfo0->in_op) != TOP_shl_i) &&
04905 ((OP_code(l2_tninfo0->in_op) != TOP_shladd) ||
04906 (OP_opnd(l2_tninfo0->in_op,3) != Zero_TN)))) return FALSE;
04907 }
04908
04909
04910 if (TN_is_constant(l2_tn1) || TN_is_symbol(l2_tn1)) return FALSE;
04911
04912
04913 l2_opinfo0 = locate_opinfo_entry(l2_tninfo0);
04914 if ((l2_opinfo0 == NULL) ||
04915 (l2_opinfo0->in_op == NULL)) return FALSE;
04916
04917 l2_op0 = l2_opinfo0->in_op;
04918 l3_tn0 = OP_opnd(l2_op0, 1);
04919 l3_tn1 = OP_opnd(l2_op0, 2);
04920 l3_tninfo0 = l2_opinfo0->actual_opnd[1];
04921 if ((l3_tn0 == NULL) || TN_Is_Constant(l3_tn0) ||
04922 (l3_tn1 == NULL) || !TN_Is_Constant(l3_tn1) ||
04923 !EBO_tn_available (bb, l3_tninfo0)) return FALSE;
04924
04925
04926 l3_val1 = TN_value(l3_tn1);
04927 if ((l3_val1 <= 0) || (l3_val1 > 4)) return FALSE;
04928
04929
04930 OP *new_op;
04931 new_op = Mk_OP(TOP_shladd, l1_tn0, OP_opnd(op,OP_PREDICATE_OPND),
04932 l3_tn0, l3_tn1, l2_tn1);
04933 OP_srcpos(new_op) = OP_srcpos(op);
04934 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND],
04935 l3_tninfo0, NULL, l2_tninfo1);
04936 BB_Insert_Op_After(bb, op, new_op);
04937 if (EBO_Trace_Optimization) fprintf(TFile,"Convert add(shl) to shladd\n");
04938 return TRUE;
04939 }
04940
04941
04942
04943
04944
04945
04946
04947
04948
04949
04950
04951
04952
04953
04954 static
04955 BOOL
04956 iadd_special_case (OP *op,
04957 TN **opnd_tn,
04958 EBO_TN_INFO **opnd_tninfo)
04959 {
04960 if (OP_code(op) == TOP_spadjust) return FALSE;
04961
04962 TN *tn = opnd_tn[1];
04963 if (TN_is_constant(tn) &&
04964 !TN_has_spill(tn) &&
04965 TN_is_symbol(tn)) {
04966 ST *st = TN_var(tn);
04967 ST *base_st;
04968 INT64 base_ofst;
04969 INT64 val = TN_offset(tn);
04970
04971 Base_Symbol_And_Offset (st, &base_st, &base_ofst);
04972 if (ST_on_stack(st) &&
04973 ((ST_sclass(st) == SCLASS_AUTO) ||
04974 (EBO_in_peep && (ST_sclass(st) == SCLASS_FORMAL)))) {
04975 val += base_ofst;
04976 if (val == 0) {
04977 OPS ops = OPS_EMPTY;
04978 EBO_Exp_COPY(OP_opnd(op,OP_PREDICATE_OPND), OP_result(op, 0), opnd_tn[2], &ops);
04979 if (EBO_in_loop) EBO_OPS_omega (&ops, opnd_tninfo[OP_PREDICATE_OPND]);
04980 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
04981 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
04982 if (EBO_Trace_Optimization) fprintf(TFile,"Replace iadd with copy\n");
04983 return TRUE;
04984 }
04985 }
04986 }
04987 return FALSE;
04988 }
04989
04990
04991
04992
04993
04994
04995
04996
04997
04998
04999
05000
05001
05002
05003 static
05004 BOOL
05005 copy_rf_sequence (OP *op,
05006 TN **opnd_tn,
05007 EBO_TN_INFO **opnd_tninfo)
05008 {
05009
05010 BB *bb = OP_bb(op);
05011 OP *l1_op0 = op;
05012 TN *l1_tn0 = OP_result(l1_op0,0);
05013
05014
05015 TOP l2_opcode;
05016 OP *l2_op0;
05017 TN *l2_tn0 = OP_opnd(op,1);
05018 EBO_TN_INFO *l2_tninfo0 = opnd_tninfo[1];
05019 EBO_OP_INFO *l2_opinfo0;
05020
05021
05022 TN *l3_tn0;
05023 EBO_TN_INFO *l3_tninfo0;
05024
05025 if ((l2_tninfo0 == NULL) ||
05026 (l2_tninfo0->in_op == NULL)) {
05027 return FALSE;
05028 }
05029
05030
05031 l2_opinfo0 = locate_opinfo_entry(l2_tninfo0);
05032 if ((l2_opinfo0 == NULL) ||
05033 (l2_opinfo0->in_op == NULL)) return FALSE;
05034 l2_op0 = l2_opinfo0->in_op;
05035 l2_opcode = OP_code(l2_op0);
05036
05037
05038
05039 if ((OP_code(op) == TOP_setf_sig) &&
05040 ((l2_opcode == TOP_ld8) ||
05041 (l2_opcode == TOP_ld8_i))) {
05042 OP *new_op;
05043 TOP new_opcode;
05044 INT i;
05045
05046
05047 if (l2_opinfo0->op_must_not_be_moved) return FALSE;
05048
05049
05050
05051
05052
05053
05054 return FALSE;
05055
05056
05057 for (i = OP_opnds(l2_op0); i >= 0; i--) {
05058 if ((l2_opinfo0->actual_opnd[i] != NULL) &&
05059 !EBO_tn_available (bb, l2_opinfo0->actual_opnd[i])) {
05060 return FALSE;
05061 }
05062 }
05063
05064
05065 new_opcode = (l2_opcode == TOP_ld8) ? TOP_ldf8 : TOP_ldf8_i;
05066
05067
05068 if (OP_opnds(l2_op0) == 4) {
05069 new_op = Mk_OP (new_opcode, l1_tn0, OP_opnd(op,OP_PREDICATE_OPND),
05070 Gen_Enum_TN(ECV_fldtype), Gen_Enum_TN(ECV_ldhint), OP_opnd(l2_op0,3));
05071 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND],
05072 l2_opinfo0->actual_opnd[1], l2_opinfo0->actual_opnd[2],
05073 l2_opinfo0->actual_opnd[3]);
05074 } else if (OP_opnds(l2_op0) == 5) {
05075 new_op = Mk_OP (new_opcode, l1_tn0, OP_opnd(op,OP_PREDICATE_OPND),
05076 Gen_Enum_TN(ECV_fldtype), Gen_Enum_TN(ECV_ldhint), OP_opnd(l2_op0,3), OP_opnd(l2_op0,4));
05077 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND],
05078 l2_opinfo0->actual_opnd[1], l2_opinfo0->actual_opnd[2],
05079 l2_opinfo0->actual_opnd[3], l2_opinfo0->actual_opnd[4]);
05080 } else return FALSE;
05081 Copy_WN_For_Memory_OP (new_op, l2_op0);
05082 OP_srcpos(new_op) = OP_srcpos(op);
05083
05084 BB_Insert_Op_After(bb, op, new_op);
05085 if (EBO_Trace_Optimization) fprintf(TFile,"load directly to fp reg.\n");
05086 return TRUE;
05087 }
05088
05089
05090 if ((l2_opcode != TOP_setf_sig) &&
05091 (l2_opcode != TOP_getf_sig)) return FALSE;
05092
05093
05094 l2_op0 = l2_opinfo0->in_op;
05095 l3_tn0 = OP_opnd(l2_op0, 1);
05096 l3_tninfo0 = l2_opinfo0->actual_opnd[1];
05097 if ((l3_tn0 == NULL) || TN_Is_Constant(l3_tn0) ||
05098 !EBO_tn_available (bb, l3_tninfo0)) return FALSE;
05099
05100 if (l2_opcode == TOP_getf_sig) {
05101 if ((l3_tninfo0 == NULL) ||
05102 (l3_tninfo0->in_op == NULL) ||
05103 ((OP_code(l3_tninfo0->in_op) != TOP_fcvt_fx) &&
05104 (OP_code(l3_tninfo0->in_op) != TOP_fcvt_fx_trunc) &&
05105 (OP_code(l3_tninfo0->in_op) != TOP_fcvt_fxu) &&
05106 (OP_code(l3_tninfo0->in_op) != TOP_fcvt_fxu_trunc) &&
05107 (OP_code(l3_tninfo0->in_op) != TOP_xma_l) &&
05108 (OP_code(l3_tninfo0->in_op) != TOP_xma_h) &&
05109 (OP_code(l3_tninfo0->in_op) != TOP_xma_lu) &&
05110 (OP_code(l3_tninfo0->in_op) != TOP_xma_hu) &&
05111 (OP_code(l3_tninfo0->in_op) != TOP_xmpy_l) &&
05112 (OP_code(l3_tninfo0->in_op) != TOP_xmpy_h) &&
05113 (OP_code(l3_tninfo0->in_op) != TOP_xmpy_lu) &&
05114 (OP_code(l3_tninfo0->in_op) != TOP_xmpy_hu))) {
05115
05116
05117
05118
05119
05120 return FALSE;
05121 }
05122 }
05123
05124 if ((TN_register_class(l1_tn0) == TN_register_class(l3_tn0)) &&
05125 ((TN_register_class(l1_tn0) == ISA_REGISTER_CLASS_integer) &&
05126 (TN_register_class(l2_tn0) == ISA_REGISTER_CLASS_float)) ||
05127 ((TN_register_class(l1_tn0) == ISA_REGISTER_CLASS_float) &&
05128 (TN_register_class(l2_tn0) == ISA_REGISTER_CLASS_integer))) {
05129
05130
05131 OPS ops = OPS_EMPTY;
05132 EBO_Exp_COPY(OP_opnd(op,OP_PREDICATE_OPND),
05133 OP_result(op,0), l3_tn0, &ops);
05134 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops),
05135 opnd_tninfo[OP_PREDICATE_OPND],
05136 l3_tninfo0);
05137 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
05138 BB_Insert_Ops(bb, op, &ops, FALSE);
05139 if (EBO_Trace_Optimization) fprintf(TFile,"copies between INT and FLOAT not needed.\n");
05140 return TRUE;
05141 }
05142 return FALSE;
05143 }
05144
05145
05146
05147
05148
05149
05150
05151
05152
05153
05154
05155
05156
05157 static
05158 BOOL
05159 store_sequence (OP *op,
05160 TN **opnd_tn,
05161 EBO_TN_INFO **opnd_tninfo)
05162 {
05163
05164 TOP opcode = OP_code(op);
05165 BB *bb = OP_bb(op);
05166 TN *l1_tn0;
05167 INT storeval_idx = TOP_Find_Operand_Use(opcode,OU_storeval);
05168 TN *store_value;
05169 EBO_TN_INFO *store_value_info;
05170 INT storebase_idx = TOP_Find_Operand_Use(opcode,OU_base);
05171 TN *storebase;
05172 EBO_TN_INFO *store_base_info;
05173 INT store_incr_idx = TOP_Find_Operand_Use(opcode, OU_postincr);
05174 TN *store_incr;
05175 EBO_TN_INFO *store_incr_info;
05176
05177
05178 TOP l2_opcode;
05179 OP *l2_op0;
05180 TN *l2_tn0 = OP_opnd(op,1);
05181 EBO_TN_INFO *l2_tninfo0 = opnd_tninfo[1];
05182 EBO_OP_INFO *l2_opinfo0;
05183
05184 TOP new_opcode = TOP_UNDEFINED;
05185 OP *new_op;
05186
05187 if (!OP_store(op) ||
05188 (storeval_idx < 0) ||
05189 (storebase_idx < 0)) return FALSE;
05190
05191
05192 storebase = OP_opnd(op,storebase_idx);
05193 store_value = OP_opnd(op,storeval_idx);
05194 store_value_info = opnd_tninfo[storeval_idx];
05195 store_base_info = opnd_tninfo[storebase_idx];
05196 store_incr_idx = TOP_Find_Operand_Use(opcode, OU_postincr);
05197 if (store_incr_idx >= 0) {
05198 store_incr = OP_opnd(op,store_incr_idx);
05199 store_incr_info = opnd_tninfo[store_incr_idx];
05200 }
05201
05202
05203
05204 if (!TN_Is_Constant(OP_opnd(op,storeval_idx)) &&
05205 TN_has_spill(OP_opnd(op,storeval_idx))) {
05206 return FALSE;
05207 }
05208
05209 l2_opinfo0 = locate_opinfo_entry(store_value_info);
05210 if ((l2_opinfo0 == NULL) ||
05211 (l2_opinfo0->in_op == NULL)) return FALSE;
05212 l2_op0 = l2_opinfo0->in_op;
05213 l2_opcode = OP_code(l2_op0);
05214
05215
05216
05217 if ((l2_opcode == TOP_getf_sig) &&
05218 ((opcode == TOP_st8) ||
05219 (opcode == TOP_st8_i))) {
05220 OP *new_op;
05221 TOP new_opcode;
05222
05223
05224 if (l2_opinfo0->op_must_not_be_moved) return FALSE;
05225
05226
05227 store_value = OP_opnd(l2_op0,1);
05228 store_value_info = l2_opinfo0->actual_opnd[1];
05229 if ((store_value_info != NULL) &&
05230 !EBO_tn_available (bb, store_value_info)) return FALSE;
05231
05232
05233 new_opcode = (opcode == TOP_st8) ? TOP_stf8 : TOP_stf8_i;
05234
05235
05236 if (new_opcode == TOP_stf8_i) {
05237 new_op = Mk_OP (new_opcode, OP_result(op,0), OP_opnd(op,OP_PREDICATE_OPND),
05238 Gen_Enum_TN(ECV_sthint), storebase, store_value, store_incr);
05239 if (EBO_in_loop) {
05240 EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND],
05241 opnd_tninfo[1], store_base_info, store_value_info, store_incr_info);
05242 }
05243 } else {
05244 new_op = Mk_OP (new_opcode, OP_opnd(op,OP_PREDICATE_OPND),
05245 Gen_Enum_TN(ECV_sthint), storebase, store_value);
05246 if (EBO_in_loop) {
05247 EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND],
05248 opnd_tninfo[1], store_base_info, store_value_info);
05249 }
05250 }
05251 Copy_WN_For_Memory_OP (new_op, op);
05252 OP_srcpos(new_op) = OP_srcpos(op);
05253
05254 BB_Insert_Op_After(bb, op, new_op);
05255 if (EBO_Trace_Optimization) fprintf(TFile,"Store directly from fp reg\n");
05256 return TRUE;
05257 }
05258
05259 if (OP_store(op) &&
05260 (storeval_idx >= 0) &&
05261 (storebase_idx >= 0) &&
05262 (OP_opnd(op,storeval_idx) != opnd_tn[storeval_idx])) {
05263 storebase = OP_opnd(op,storebase_idx);
05264 l1_tn0 = OP_opnd(op,storeval_idx);
05265 l2_tn0 = opnd_tn[storeval_idx];
05266 l2_tninfo0 = opnd_tninfo[storeval_idx];
05267 if ((l2_tn0 == NULL) ||
05268 TN_Is_Constant(l2_tn0) ||
05269 (l2_tninfo0 == NULL) ||
05270 (l2_tninfo0->in_op == NULL) ||
05271 (TN_size(l1_tn0) > TN_size(l2_tn0)) ||
05272 (CGTARG_Mem_Ref_Bytes(op) > TN_size(l2_tn0)) ||
05273 !EBO_tn_available (bb, l2_tninfo0)) {
05274 return FALSE;
05275 }
05276
05277 switch (opcode) {
05278 case TOP_st4:
05279 if (l2_opcode == TOP_getf_s) {
05280 new_opcode = TOP_stfs;
05281 } else return FALSE;
05282 break;
05283 case TOP_st4_i:
05284 if (l2_opcode == TOP_getf_s) {
05285 new_opcode = TOP_stfs_i;
05286 } else return FALSE;
05287 break;
05288 case TOP_st8:
05289 if (l2_opcode == TOP_getf_sig) {
05290 new_opcode = TOP_stf8;
05291 } else if (l2_opcode == TOP_getf_d) {
05292 new_opcode = TOP_stfd;
05293 } else return FALSE;
05294 break;
05295 case TOP_st8_i:
05296 if (l2_opcode == TOP_getf_sig) {
05297 new_opcode = TOP_stf8_i;
05298 } else if (l2_opcode == TOP_getf_d) {
05299 new_opcode = TOP_stfd_i;
05300 } else return FALSE;
05301 break;
05302 case TOP_stf8: new_opcode = TOP_st8; break;
05303 case TOP_stf8_i: new_opcode = TOP_st8_i; break;
05304 case TOP_stfs:
05305 case TOP_stfd:
05306 default: return FALSE;
05307 }
05308
05309 if ((TN_register_class(l1_tn0) == ISA_REGISTER_CLASS_integer) &&
05310 (TN_register_class(l2_tn0) == ISA_REGISTER_CLASS_float)) {
05311 TN *st_hint = OP_opnd(op,2);
05312 if ((new_opcode == TOP_stf8_i) ||
05313 (new_opcode == TOP_stfd_i) ||
05314 (new_opcode == TOP_stfs_i)) {
05315 new_op = Mk_OP (new_opcode, OP_result(op,0), OP_opnd(op,OP_PREDICATE_OPND),
05316 st_hint, storebase, l2_tn0,
05317 OP_opnd(op, TOP_Find_Operand_Use(opcode, OU_postincr)));
05318 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND],
05319 NULL, opnd_tninfo[storebase_idx], opnd_tninfo[storeval_idx], NULL);
05320 } else {
05321 new_op = Mk_OP (new_opcode, OP_opnd(op,OP_PREDICATE_OPND),
05322 st_hint, storebase, l2_tn0);
05323 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND],
05324 NULL, opnd_tninfo[storebase_idx], opnd_tninfo[storeval_idx]);
05325 }
05326
05327 Copy_WN_For_Memory_OP (new_op, op);
05328 OP_srcpos(new_op) = OP_srcpos(op);
05329 BB_Insert_Op_After( bb, op, new_op);
05330 if (EBO_Trace_Optimization) fprintf(TFile,"Replace INT store with FP store\n");
05331 return TRUE;
05332 }
05333
05334 if ((TN_register_class(l1_tn0) == ISA_REGISTER_CLASS_float) &&
05335 (TN_register_class(l2_tn0) == ISA_REGISTER_CLASS_integer)) {
05336 TN *st_hint = OP_opnd(op,1);
05337 if (new_opcode == TOP_st8_i) {
05338 new_op = Mk_OP (new_opcode, OP_result(op,0), OP_opnd(op,OP_PREDICATE_OPND),
05339 Gen_Enum_TN(ECV_sttype), st_hint, storebase, l2_tn0,
05340 OP_opnd(op, TOP_Find_Operand_Use(opcode, OU_postincr)));
05341 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND],
05342 NULL, NULL, opnd_tninfo[storebase_idx], opnd_tninfo[storeval_idx], NULL);
05343 } else {
05344 new_op = Mk_OP (new_opcode, OP_opnd(op,OP_PREDICATE_OPND),
05345 Gen_Enum_TN(ECV_sttype), st_hint, storebase, l2_tn0);
05346 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND],
05347 NULL, NULL, opnd_tninfo[storebase_idx], opnd_tninfo[storeval_idx]);
05348 }
05349
05350 Copy_WN_For_Memory_OP (new_op, op);
05351 OP_srcpos(new_op) = OP_srcpos(op);
05352 BB_Insert_Op_After( bb, op, new_op);
05353 if (EBO_Trace_Optimization) fprintf(TFile,"Replace FP store with INT store\n");
05354 return TRUE;
05355 }
05356
05357 }
05358
05359 return FALSE;
05360 }
05361
05362
05363
05364
05365
05366
05367 static
05368 OP *
05369 Generate_Extract(TOP extr_opc,
05370 TN *dest,
05371 TN *pred,
05372 TN *src,
05373 INT pos,
05374 INT len)
05375 {
05376 if (pos == 0) {
05377 BOOL is_signed = (extr_opc == TOP_extr);
05378
05379 if (len == 8 || len == 16 || len == 32) {
05380 TOP new_opc;
05381 switch (len >> 3) {
05382 case 1: new_opc = is_signed ? TOP_sxt1 : TOP_zxt1; break;
05383 case 2: new_opc = is_signed ? TOP_sxt2 : TOP_zxt2; break;
05384 case 4: new_opc = is_signed ? TOP_sxt4 : TOP_zxt4; break;
05385 }
05386 return Mk_OP(new_opc, dest, pred, src);
05387 } else if (!is_signed) {
05388 UINT64 mask = -1ULL >> (64 - len);
05389 if (ISA_LC_Value_In_Class(mask, LC_i8)) {
05390 return Mk_OP(TOP_and_i, dest, pred, Gen_Literal_TN(mask, 4), src);
05391 }
05392 }
05393 }
05394
05395 return Mk_OP(extr_opc, dest, pred, src,
05396 Gen_Literal_TN(pos, 4), Gen_Literal_TN(len, 4));
05397 }
05398
05399
05400
05401
05402
05403
05404
05405
05406
05407
05408
05409
05410
05411
05412
05413
05414
05415
05416
05417
05418
05419
05420
05421
05422
05423
05424
05425
05426
05427
05428
05429
05430
05431
05432
05433 static
05434 BOOL
05435 sxt_sequence (OP *op,
05436 INT op_idx,
05437 TN **opnd_tn,
05438 EBO_TN_INFO **opnd_tninfo)
05439 {
05440
05441 TOP opcode = OP_code(op);
05442 BB *bb = OP_bb(op);
05443 INT sxt_idx = 1;
05444 EBO_TN_INFO *sxt_tninfo;
05445
05446 OP *pred_op;
05447 TOP pred_opcode;
05448
05449 INT result_start = 0;
05450 INT result_length;
05451 INT input_start = 0;
05452 INT input_length;
05453
05454 if (sxt_idx < 0) return FALSE;
05455
05456 if (EBO_Trace_Execution) {
05457 #pragma mips_frequency_hint NEVER
05458 fprintf(TFile,"Enter sxt_sequence\n");
05459 }
05460
05461 sxt_tninfo = opnd_tninfo[op_idx];
05462
05463 if ((sxt_tninfo == NULL) ||
05464 (sxt_tninfo->in_op == NULL)) return FALSE;
05465
05466
05467
05468 if (OP_store(op)) {
05469 TN *store_value = OP_opnd(op,op_idx);
05470 if (!TN_Is_Constant(store_value) &&
05471 TN_has_spill(store_value)) {
05472 return FALSE;
05473 }
05474 }
05475
05476 pred_op = sxt_tninfo->in_op;
05477 pred_opcode = OP_code(pred_op);
05478
05479
05480 if ((pred_opcode == TOP_and) ||
05481 (pred_opcode == TOP_andcm)) {
05482 EBO_OP_INFO *and_opinfo = locate_opinfo_entry (sxt_tninfo);
05483 if ((and_opinfo == NULL) ||
05484 (and_opinfo->in_op == NULL)) return FALSE;
05485 EBO_TN_INFO *pred_info1 = and_opinfo->actual_opnd[1];
05486 EBO_TN_INFO *pred_info2 = and_opinfo->actual_opnd[2];
05487 TN *pred_op1;
05488 TN *pred_op2;
05489 TN *mask_tn;
05490 INT32 mask_size;
05491 INT32 mask_shift;
05492
05493 if (pred_info1 != NULL) {
05494 if (pred_info1->replacement_tn != NULL) {
05495 pred_op1 = pred_info1->replacement_tn;
05496 } else {
05497 pred_op1 = pred_info1->local_tn;
05498 }
05499 } else {
05500 pred_op1 = OP_opnd(pred_op,1);
05501 }
05502 if (pred_info2 != NULL) {
05503 if (pred_info2->replacement_tn != NULL) {
05504 pred_op2 = pred_info2->replacement_tn;
05505 } else {
05506 pred_op2 = pred_info2->local_tn;
05507 }
05508 } else {
05509 pred_op2 = OP_opnd(pred_op,2);
05510 }
05511
05512 if (TN_Is_Constant(pred_op1)) {
05513 mask_tn = pred_op1;
05514 mask_shift = Get_Mask_Shift_Count( TN_Value(mask_tn) );
05515 mask_size = Get_Right_Mask_Length( TN_Value(mask_tn) >> mask_shift);
05516 } else if (TN_Is_Constant(pred_op2)) {
05517 mask_tn = pred_op2;
05518 if ((pred_opcode == TOP_andcm) || (pred_opcode == TOP_andcm_i)) {
05519 mask_shift = Get_Mask_Shift_Count( ~TN_Value(mask_tn) );
05520 mask_size = Get_Right_Mask_Length( ~TN_Value(mask_tn) >> mask_shift);
05521 } else {
05522 mask_shift = Get_Mask_Shift_Count( TN_Value(mask_tn) );
05523 mask_size = Get_Right_Mask_Length( ((UINT64)TN_Value(mask_tn) >> mask_shift) );
05524 }
05525 } else return FALSE;
05526
05527 input_start = mask_shift;
05528 input_length = mask_size;
05529
05530 if (input_start != 0) return FALSE;
05531
05532 } else {
05533 input_length = EBO_bit_length(pred_op);
05534 }
05535
05536 result_length = EBO_bit_length (op);
05537 if ((result_length < 0) || (input_length < 0)) return FALSE;
05538
05539
05540 if ((opcode == TOP_extr) || (opcode == TOP_extr_u) ||
05541 (opcode == TOP_shr_i) || (opcode == TOP_shr_i_u)) {
05542 result_start = TN_Value( OP_opnd(op,2) );
05543 }
05544 if ((pred_opcode == TOP_extr) || (pred_opcode == TOP_extr_u) ||
05545 (pred_opcode == TOP_shr_i) || (pred_opcode == TOP_shr_i_u)) {
05546 input_start = TN_Value( OP_opnd(pred_op,2) );
05547 }
05548 if (pred_opcode == TOP_dep) {
05549 INT p_start = TN_Value( OP_opnd(pred_op,3) );
05550 if (((result_start + result_length) <= p_start) ||
05551 ((p_start + input_length) <= result_start)) {
05552
05553
05554 input_start = 0;
05555 input_length = 64;
05556 sxt_idx = 2;
05557 } else if ((p_start == result_start) &&
05558 ((result_start + result_length) <= (p_start + input_length))) {
05559
05560 result_start = 0;
05561 } else if ((opcode == TOP_extr_u) &&
05562 (result_start == 0) &&
05563 ((p_start + input_length) <= result_length)) {
05564
05565
05566
05567 EBO_OP_INFO *dep_opinfo = locate_opinfo_entry (sxt_tninfo);
05568 if ((dep_opinfo == NULL) ||
05569 (dep_opinfo->in_op == NULL)) return FALSE;
05570 EBO_TN_INFO *dep_info1 = dep_opinfo->optimal_opnd[2];
05571 if ((dep_info1 != NULL) &&
05572 (dep_info1->in_op != NULL) &&
05573 (EBO_bit_length(dep_info1->in_op) <= result_length)) {
05574
05575
05576 OPS ops = OPS_EMPTY;
05577 EBO_Exp_COPY(OP_opnd(op,OP_PREDICATE_OPND),
05578 OP_result(op,0), OP_opnd(op, op_idx), &ops);
05579
05580 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops),
05581 opnd_tninfo[OP_PREDICATE_OPND],
05582 opnd_tninfo[op_idx]);
05583 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
05584 BB_Insert_Ops(bb, op, &ops, FALSE);
05585 if (EBO_Trace_Optimization) {
05586 #pragma mips_frequency_hint NEVER
05587 fprintf(TFile,"%s of %s replaced with copy of input\n",
05588 TOP_Name(opcode), TOP_Name(pred_opcode));
05589 }
05590
05591 return TRUE;
05592 }
05593
05594 return FALSE;
05595 } else {
05596
05597 return FALSE;
05598 }
05599 }
05600 if (pred_opcode == TOP_dep_z) {
05601 INT p_start = TN_Value( OP_opnd(pred_op,2) );
05602 if (((result_start + result_length) <= p_start) ||
05603 ((p_start + input_length) <= result_start)) {
05604
05605
05606
05607
05608 OP *new_op = Dup_OP(op);
05609 Set_OP_opnd (new_op, op_idx, Zero_TN);
05610 if (OP_store(op)) {
05611 Copy_WN_For_Memory_OP (new_op, op);
05612 }
05613
05614 if (EBO_in_loop) {
05615 EBO_Copy_OP_omega (new_op, op);
05616 Set_OP_omega (op, op_idx, 0);
05617 }
05618
05619 BB_Insert_Op_After(bb, op, new_op);
05620 if (EBO_Trace_Optimization) {
05621 #pragma mips_frequency_hint NEVER
05622 fprintf(TFile,"OP does not access inserted field of dep_z.\n");
05623 }
05624
05625 return TRUE;
05626 } else if ((p_start <= result_start) &&
05627 ((result_start + result_length) <= (p_start + input_length))) {
05628
05629 result_start = result_start - p_start;
05630 } else {
05631
05632 return FALSE;
05633 }
05634 }
05635
05636 BOOL input_zxt = (pred_opcode == TOP_and_i) ||
05637 (pred_opcode == TOP_and) ||
05638 (pred_opcode == TOP_andcm) ||
05639 (pred_opcode == TOP_andcm_i) ||
05640 (pred_opcode == TOP_dep) ||
05641 (pred_opcode == TOP_dep_z) ||
05642 (pred_opcode == TOP_extr_u) ||
05643 (pred_opcode == TOP_shr_i_u) ||
05644 (pred_opcode == TOP_zxt1) ||
05645 (pred_opcode == TOP_zxt2) ||
05646 (pred_opcode == TOP_zxt4);
05647 BOOL input_sxt = (pred_opcode == TOP_extr) ||
05648 (pred_opcode == TOP_shr_i) ||
05649 (pred_opcode == TOP_sxt1) ||
05650 (pred_opcode == TOP_sxt2) ||
05651 (pred_opcode == TOP_sxt4);
05652 BOOL result_zxt = (opcode == TOP_and_i) ||
05653 (opcode == TOP_extr_u) ||
05654 (opcode == TOP_shr_i_u) ||
05655 (opcode == TOP_zxt1) ||
05656 (opcode == TOP_zxt2) ||
05657 (opcode == TOP_zxt4);
05658 BOOL result_sxt = (opcode == TOP_extr) ||
05659 (opcode == TOP_shr_i) ||
05660 (opcode == TOP_sxt1) ||
05661 (opcode == TOP_sxt2) ||
05662 (opcode == TOP_sxt4);
05663
05664
05665
05666
05667
05668 if ((input_zxt || input_sxt) && (result_zxt || result_sxt)) {
05669
05670
05671
05672
05673
05674
05675 INT input_shift = 0;
05676 if ((pred_opcode == TOP_extr_u) || (pred_opcode == TOP_extr) ||
05677 (pred_opcode == TOP_dep_z) || (pred_opcode == TOP_dep) ||
05678 (pred_opcode == TOP_shr_i_u) || (pred_opcode == TOP_shr_i)) {
05679 input_shift = input_start;
05680 input_start = 0;
05681 }
05682
05683
05684
05685 INT input_end = input_start + input_length;
05686 INT result_end = result_start + result_length;
05687 INT new_end = MIN(input_end, result_end);
05688 INT new_start = MAX(input_start, result_start);
05689 INT new_length = new_end - new_start;
05690 new_start += input_shift;
05691
05692 if (new_length <= 0) {
05693
05694 if (input_sxt && (result_start >= input_length)) return FALSE;
05695
05696
05697 OPS ops = OPS_EMPTY;
05698 EBO_Exp_COPY(OP_opnd(op,OP_PREDICATE_OPND),
05699 OP_result(op,0), Zero_TN, &ops);
05700 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops),
05701 opnd_tninfo[OP_PREDICATE_OPND],
05702 NULL);
05703 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
05704 BB_Insert_Ops(bb, op, &ops, FALSE);
05705 if (EBO_Trace_Optimization) {
05706 #pragma mips_frequency_hint NEVER
05707 fprintf(TFile,"%s of %s replaced with copy of zero\n",
05708 TOP_Name(opcode), TOP_Name(pred_opcode));
05709 }
05710
05711 return TRUE;
05712 }
05713
05714
05715
05716 TOP new_opc = TOP_extr_u;
05717 if (result_sxt) {
05718 if (input_sxt || result_end <= input_end) new_opc = TOP_extr;
05719 } else if (input_sxt) {
05720 if (result_end > input_end) return FALSE;
05721 }
05722
05723
05724
05725 EBO_OP_INFO *and_opinfo = locate_opinfo_entry (sxt_tninfo);
05726 INT and_idx = (pred_opcode == TOP_and_i) ? 2 : sxt_idx;
05727 if ((and_opinfo == NULL) ||
05728 (and_opinfo->in_op == NULL) ||
05729 (and_opinfo->actual_opnd[and_idx] == NULL) ||
05730 (!EBO_tn_available(bb, and_opinfo->actual_opnd[and_idx]))) return FALSE;
05731
05732
05733
05734 TN *src = OP_opnd(pred_op,and_idx);
05735 OP *new_op = Generate_Extract(new_opc, OP_result(op,0), OP_opnd(op,0),
05736 src, new_start, new_length);
05737 INT src_idx = TN_Opernum_In_OP (new_op, src);
05738 new_opc = OP_code(new_op);
05739 OP_srcpos(new_op) = OP_srcpos(op);
05740 if (EBO_in_loop) {
05741
05742
05743 OPS ops = OPS_EMPTY;
05744 OPS_Insert_Op (&ops, NULL, new_op, TRUE);
05745 EBO_TN_INFO *and_tninfo = and_opinfo->actual_opnd[and_idx];
05746 EBO_OPS_omega (&ops, opnd_tninfo[OP_PREDICATE_OPND]);
05747 Set_OP_omega (new_op, src_idx, (and_tninfo != NULL) ? and_tninfo->omega : 0);
05748 }
05749 BB_Insert_Op_After(OP_bb(op), op, new_op);
05750
05751 if (EBO_Trace_Optimization) {
05752 #pragma mips_frequency_hint NEVER
05753 fprintf(TFile,"%s of %s replaced with %s.\n",
05754 TOP_Name(opcode), TOP_Name(pred_opcode), TOP_Name(new_opc));
05755 }
05756 return TRUE;
05757 } else if (OP_load(pred_op)) {
05758
05759 if (result_start == 0 &&
05760 ((result_zxt && result_length >= input_length) ||
05761 (result_sxt && result_length > input_length)))
05762 {
05763
05764 OPS ops = OPS_EMPTY;
05765 EBO_Exp_COPY(OP_opnd(op,OP_PREDICATE_OPND),
05766 OP_result(op,0), opnd_tn[op_idx], &ops);
05767 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops),
05768 opnd_tninfo[OP_PREDICATE_OPND],
05769 opnd_tninfo[op_idx]);
05770 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
05771 BB_Insert_Ops(bb, op, &ops, FALSE);
05772 if (EBO_Trace_Optimization) {
05773 #pragma mips_frequency_hint NEVER
05774 fprintf(TFile,"skip %s after load operation\n", TOP_Name(opcode));
05775 }
05776
05777 return TRUE;
05778 }
05779 } else if (OP_store(op) || OP_icmp(op) ||
05780 opcode == TOP_dep || opcode == TOP_dep_z)
05781 {
05782 if (input_start == 0 && input_length >= result_length) {
05783
05784
05785
05786
05787 EBO_OP_INFO *sxt_opinfo = locate_opinfo_entry (sxt_tninfo);
05788 if ((sxt_opinfo == NULL) ||
05789 (sxt_opinfo->in_op == NULL) ||
05790 (sxt_opinfo->actual_opnd[sxt_idx] == NULL) ||
05791 (!EBO_tn_available(bb, sxt_opinfo->actual_opnd[sxt_idx]))) return FALSE;
05792
05793
05794 OP *new_op = Dup_OP (op);
05795 Set_OP_opnd (new_op, op_idx, OP_opnd(pred_op,sxt_idx));
05796 OP_srcpos(new_op) = OP_srcpos(op);
05797 if (OP_store(op)) {
05798 Copy_WN_For_Memory_OP (new_op, op);
05799 if (EBO_in_loop) {
05800 if (OP_opnds(op) == 5) {
05801 EBO_Set_OP_omega (new_op, opnd_tninfo[OP_PREDICATE_OPND],
05802 NULL, NULL, NULL, sxt_opinfo->actual_opnd[sxt_idx]);
05803 } else if (OP_opnds(op) == 6) {
05804
05805 EBO_Set_OP_omega (new_op, opnd_tninfo[OP_PREDICATE_OPND],
05806 NULL, NULL, NULL, sxt_opinfo->actual_opnd[sxt_idx], NULL);
05807 } else return FALSE;
05808 }
05809 } else if (EBO_in_loop) {
05810 EBO_TN_INFO *sxt_tninfo = sxt_opinfo->actual_opnd[sxt_idx];
05811 EBO_TN_INFO *pred_tninfo = opnd_tninfo[OP_PREDICATE_OPND];
05812 if (OP_opnds(op) == 2) {
05813
05814 EBO_Set_OP_omega (new_op, pred_tninfo, sxt_tninfo);
05815 } else if ((OP_opnds(op) == 3) && (op_idx == 1)) {
05816
05817 EBO_Set_OP_omega (new_op, pred_tninfo, sxt_tninfo, opnd_tninfo[2]);
05818 } else if ((OP_opnds(op) == 3) && (op_idx == 2)) {
05819
05820 EBO_Set_OP_omega (new_op, pred_tninfo, opnd_tninfo[1], sxt_tninfo);
05821 } else if ((OP_opnds(op) == 4) && (op_idx == 1)) {
05822
05823 EBO_Set_OP_omega (new_op, pred_tninfo, sxt_tninfo, opnd_tninfo[2],
05824 opnd_tninfo[3]);
05825 } else if ((OP_opnds(op) == 5) && (op_idx == 1)) {
05826
05827 EBO_Set_OP_omega (new_op, pred_tninfo, sxt_tninfo, opnd_tninfo[2],
05828 opnd_tninfo[3], opnd_tninfo[4]);
05829 } else return FALSE;
05830 }
05831 BB_Insert_Op_After(OP_bb(op), op, new_op);
05832 if (EBO_Trace_Optimization) {
05833 #pragma mips_frequency_hint NEVER
05834 fprintf(TFile,"bypass %s before %s operation\n",
05835 TOP_Name(pred_opcode), TOP_Name(opcode));
05836 }
05837
05838 return TRUE;
05839 }
05840 }
05841
05842 return FALSE;
05843 }
05844
05845
05846
05847 static
05848 void
05849 EBO_Identify_Base_and_Offset (EBO_TN_INFO **opnd_tninfo, TN **opnd_tn, INT64 *opnd_offset)
05850 {
05851 EBO_TN_INFO *check_tninfo = *opnd_tninfo;
05852 TN *indx_tn = *opnd_tn;
05853 INT64 offset = 0;
05854 BOOL keep_going = TRUE;
05855
05856 while (keep_going && (check_tninfo != NULL)) {
05857 keep_going = FALSE;
05858 EBO_OP_INFO *opnd_opinfo = locate_opinfo_entry(check_tninfo);
05859 if ((opnd_opinfo != NULL) &&
05860 (opnd_opinfo->in_op != NULL)) {
05861 OP *input_op = opnd_opinfo->in_op;
05862 if (OP_effectively_copy(input_op)) {
05863 check_tninfo = opnd_opinfo->actual_opnd[EBO_Copy_Operand(input_op)];
05864 indx_tn = OP_opnd(input_op,EBO_Copy_Operand(input_op));
05865 keep_going = TRUE;
05866 } else if (OP_memory(input_op)) {
05867 INT base_idx = TOP_Find_Operand_Use(OP_code(input_op),OU_base);
05868 INT inc_idx = TOP_Find_Operand_Use(OP_code(input_op),OU_postincr);
05869 if ((inc_idx < 0) || (!TNs_Are_Equivalent(OP_opnd(input_op,base_idx),check_tninfo->local_tn))) {
05870 check_tninfo = NULL;
05871 break;
05872 }
05873 offset += TN_Value(OP_opnd(input_op,inc_idx));
05874 check_tninfo = opnd_opinfo->actual_opnd[base_idx];
05875 indx_tn = OP_opnd(input_op,base_idx);
05876 keep_going = TRUE;
05877 } else if (OP_iadd(input_op)) {
05878 INT op1_idx = TOP_Find_Operand_Use(OP_code(input_op),OU_opnd1);
05879 INT op2_idx = TOP_Find_Operand_Use(OP_code(input_op),OU_opnd2);
05880
05881 if ((op1_idx >= 0) && (op2_idx >= 0)) {
05882 EBO_TN_INFO *tmp1_tninfo = opnd_opinfo->actual_opnd[op1_idx];
05883 EBO_TN_INFO *tmp2_tninfo = opnd_opinfo->actual_opnd[op2_idx];
05884 TN *tmp1_tn;
05885 TN *tmp2_tn;
05886 if (tmp1_tninfo != NULL) {
05887 if ((tmp1_tninfo->replacement_tn) &&
05888 (TN_is_symbol(tmp1_tninfo->replacement_tn) || TN_Is_Constant(tmp1_tninfo->replacement_tn))) {
05889 tmp1_tn = tmp1_tninfo->replacement_tn;
05890 tmp1_tninfo = tmp1_tninfo->replacement_tninfo;
05891 } else {
05892 tmp1_tn = tmp1_tninfo->local_tn;
05893 }
05894 } else {
05895 tmp1_tn = OP_opnd(input_op,op1_idx);
05896 }
05897 if (tmp2_tninfo != NULL) {
05898 if ((tmp2_tninfo->replacement_tn) &&
05899 (TN_is_symbol(tmp2_tninfo->replacement_tn) || TN_Is_Constant(tmp2_tninfo->replacement_tn))) {
05900 tmp2_tn = tmp2_tninfo->replacement_tn;
05901 tmp2_tninfo = tmp2_tninfo->replacement_tninfo;
05902 } else {
05903 tmp2_tn = tmp2_tninfo->local_tn;
05904 }
05905 } else {
05906 tmp2_tn = OP_opnd(input_op,op2_idx);
05907 }
05908
05909 if (!TN_is_symbol(tmp1_tn) && TN_Is_Constant(tmp1_tn)) {
05910 offset += TN_Value(tmp1_tn);
05911 check_tninfo = tmp2_tninfo;
05912 indx_tn = tmp2_tn;
05913 keep_going = TRUE;
05914 } else if (!TN_is_symbol(tmp2_tn) && TN_Is_Constant(tmp2_tn)) {
05915 offset += TN_Value(tmp2_tn);
05916 check_tninfo = tmp1_tninfo;
05917 indx_tn = tmp1_tn;
05918 keep_going = TRUE;
05919 }
05920 }
05921
05922 } else if (EBO_Trace_Data_Flow) {
05923 #pragma mips_frequency_hint NEVER
05924 fprintf(TFile,"%sNon-simple expression in symbolic compare opnd[1] ",EBO_trace_pfx);
05925 Print_OP_No_SrcLine(input_op);
05926 }
05927 }
05928 }
05929
05930 *opnd_tninfo = check_tninfo;
05931 *opnd_tn = indx_tn;
05932 *opnd_offset = offset;
05933 }
05934
05935
05936
05937 static
05938 BOOL
05939 condition_optimization(OP *op,
05940 TN **opnd_tn,
05941 EBO_TN_INFO **opnd_tninfo)
05942 {
05943 INT op1_idx = TOP_Find_Operand_Use(OP_code(op),OU_opnd1);
05944 INT op2_idx = TOP_Find_Operand_Use(OP_code(op),OU_opnd2);
05945 TN *op1 = opnd_tn[op1_idx];
05946 TN *op2 = opnd_tn[op2_idx];
05947
05948 EBO_TN_INFO *op1_tninfo = opnd_tninfo[op1_idx];
05949 EBO_TN_INFO *op2_tninfo = opnd_tninfo[op2_idx];
05950
05951 INT64 op1_offset = TN_Is_Constant(op1) ? TN_value(op1) : 0;
05952 INT64 op2_offset = TN_Is_Constant(op2) ? TN_value(op2) : 0;
05953
05954
05955 if ((op1 == op2) && (op1 != Zero_TN)) {
05956 OPS ops = OPS_EMPTY;
05957
05958 TOP opcode = OP_code(op);
05959 TN *r0 = OP_result(op,0);
05960 TN *r1 = OP_result(op,1);
05961 TN *prd = OP_opnd(op,OP_PREDICATE_OPND);
05962
05963
05964
05965 if (r0 != True_TN) {
05966 Build_OP (opcode, r0, True_TN, prd, Zero_TN, Zero_TN, &ops);
05967 OP_srcpos(OPS_last(&ops)) = OP_srcpos(op);
05968 if (OP_glue(op)) Set_OP_glue(OPS_first(&ops));
05969 }
05970 if (r1 != True_TN) {
05971 Build_OP (opcode, True_TN, r1, prd, Zero_TN, Zero_TN, &ops);
05972 OP_srcpos(OPS_last(&ops)) = OP_srcpos(op);
05973 if (OP_glue(op)) Set_OP_glue(OPS_first(&ops));
05974 }
05975 if (EBO_in_loop) EBO_OPS_omega (&ops, opnd_tninfo[OP_PREDICATE_OPND]);
05976 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
05977
05978 if (EBO_Trace_Optimization) {
05979 #pragma mips_frequency_hint NEVER
05980 fprintf(TFile,"%sResolve compare symbolically.\n",EBO_trace_pfx);
05981 }
05982
05983 return TRUE;
05984 }
05985
05986 EBO_Identify_Base_and_Offset ( &op1_tninfo, &op1, &op1_offset);
05987 EBO_Identify_Base_and_Offset ( &op2_tninfo, &op2, &op2_offset);
05988
05989 if ((op1_tninfo == op2_tninfo) && (op1_tninfo != NULL) && (op1 != Zero_TN)) {
05990 TOP opcode = OP_code(op);
05991 if ( opcode == TOP_cmp_geu ||
05992 opcode == TOP_cmp_geu_unc ||
05993 opcode == TOP_cmp_ltu ||
05994 opcode == TOP_cmp_ltu_unc ||
05995 opcode == TOP_cmp_gtu ||
05996 opcode == TOP_cmp_gtu_unc ||
05997 opcode == TOP_cmp_leu ||
05998 opcode == TOP_cmp_leu_unc ||
05999 opcode == TOP_cmp_i_geu ||
06000 opcode == TOP_cmp_i_geu_unc ||
06001 opcode == TOP_cmp_i_ltu ||
06002 opcode == TOP_cmp_i_ltu_unc ||
06003 opcode == TOP_cmp_i_gtu ||
06004 opcode == TOP_cmp_i_gtu_unc ||
06005 opcode == TOP_cmp_i_leu ||
06006 opcode == TOP_cmp_i_leu_unc) {
06007 return FALSE;
06008 }
06009 if (EBO_Trace_Optimization) {
06010 #pragma mips_frequency_hint NEVER
06011 fprintf(TFile,"%sResolve compare symbolically by reducing to constants %lld : %lld.\n",
06012 EBO_trace_pfx,op1_offset,op2_offset);
06013 }
06014
06015 TN *new_tn[OP_MAX_FIXED_OPNDS];
06016 TN **new_opnd_tn = &new_tn[0];
06017 EBO_TN_INFO *new_tninfo[OP_MAX_FIXED_OPNDS];
06018 EBO_TN_INFO **new_opnd_tninfo = &new_tninfo[0];
06019 for (INT i = 0; i < OP_opnds(op); i++) {
06020 new_tn[i] = NULL;
06021 new_tninfo[i] = NULL;
06022 }
06023 new_tn[OP_PREDICATE_OPND] = OP_opnd(op,OP_PREDICATE_OPND);
06024 new_tninfo[OP_PREDICATE_OPND] = opnd_tninfo[OP_PREDICATE_OPND];
06025 new_tn[op1_idx] = Gen_Literal_TN(op1_offset, 8);
06026 new_tn[op2_idx] = Gen_Literal_TN(op2_offset, 8);
06027 return Fold_Constant_Expression (op, new_opnd_tn, new_opnd_tninfo);
06028
06029 return TRUE;
06030 }
06031
06032 TOP opcode = OP_code(op);
06033 BB *bb = OP_bb(op);
06034
06035 if ((opcode == TOP_cmp_eq) ||
06036 (opcode == TOP_cmp_eq_unc) ||
06037 (opcode == TOP_cmp_ne) ||
06038 (opcode == TOP_cmp_ne_unc) ||
06039 (opcode == TOP_cmp_ge) ||
06040 (opcode == TOP_cmp_ge_unc) ||
06041 (opcode == TOP_cmp_geu) ||
06042 (opcode == TOP_cmp_geu_unc) ||
06043 (opcode == TOP_cmp_lt) ||
06044 (opcode == TOP_cmp_lt_unc) ||
06045 (opcode == TOP_cmp_ltu) ||
06046 (opcode == TOP_cmp_ltu_unc) ||
06047 (opcode == TOP_cmp_gt) ||
06048 (opcode == TOP_cmp_gt_unc) ||
06049 (opcode == TOP_cmp_gtu) ||
06050 (opcode == TOP_cmp_gtu_unc) ||
06051 (opcode == TOP_cmp_le) ||
06052 (opcode == TOP_cmp_le_unc) ||
06053 (opcode == TOP_cmp_leu) ||
06054 (opcode == TOP_cmp_leu_unc) ||
06055 (opcode == TOP_cmp_i_eq) ||
06056 (opcode == TOP_cmp_i_eq_unc) ||
06057 (opcode == TOP_cmp_i_ne) ||
06058 (opcode == TOP_cmp_i_ne_unc) ||
06059 (opcode == TOP_cmp_i_ge) ||
06060 (opcode == TOP_cmp_i_ge_unc) ||
06061 (opcode == TOP_cmp_i_geu) ||
06062 (opcode == TOP_cmp_i_geu_unc) ||
06063 (opcode == TOP_cmp_i_lt) ||
06064 (opcode == TOP_cmp_i_lt_unc) ||
06065 (opcode == TOP_cmp_i_ltu) ||
06066 (opcode == TOP_cmp_i_ltu_unc) ||
06067 (opcode == TOP_cmp_i_gt) ||
06068 (opcode == TOP_cmp_i_gt_unc) ||
06069 (opcode == TOP_cmp_i_gtu) ||
06070 (opcode == TOP_cmp_i_gtu_unc) ||
06071 (opcode == TOP_cmp_i_le) ||
06072 (opcode == TOP_cmp_i_le_unc) ||
06073 (opcode == TOP_cmp_i_leu) ||
06074 (opcode == TOP_cmp_i_leu_unc)) {
06075
06076
06077 OP *l2_op0;
06078 TOP l2_opcode0 = TOP_UNDEFINED;
06079 TN *l2_tn0 = opnd_tn[1];
06080 INT64 l2_val0;
06081 EBO_TN_INFO *l2_tninfo0 = opnd_tninfo[1];
06082 EBO_OP_INFO *l2_opinfo0;
06083 OP *l2_op1;
06084 TOP l2_opcode1 = TOP_UNDEFINED;
06085 TN *l2_tn1 = opnd_tn[2];
06086 INT64 l2_val1;
06087 EBO_TN_INFO *l2_tninfo1 = opnd_tninfo[2];
06088 EBO_OP_INFO *l2_opinfo1;
06089
06090
06091 TOP new_opcode;
06092 TN *l3_tn0;
06093 EBO_TN_INFO *l3_tninfo0;
06094 TN *l3_tn1;
06095 EBO_TN_INFO *l3_tninfo1;
06096
06097 if ((l2_tninfo1 != NULL) &&
06098 (l2_tninfo1->in_op != NULL)) {
06099 l2_op1 = l2_tninfo1->in_op;
06100 l2_opcode1 = OP_code(l2_op1);
06101
06102 if ((l2_opcode1 != TOP_sxt4) &&
06103 (l2_opcode1 != TOP_zxt4)) return FALSE;
06104
06105 l2_opinfo1 = locate_opinfo_entry (l2_tninfo1);
06106 if (l2_opinfo1 == NULL) return FALSE;
06107 if (l2_opinfo1->actual_opnd[1] == NULL) return FALSE;
06108 if (!EBO_tn_available(bb, l2_opinfo1->actual_opnd[1])) return FALSE;
06109
06110 l3_tn1 = OP_opnd(l2_op1,1);
06111 l3_tninfo1 = l2_opinfo1->actual_opnd[1];
06112 } else if (TN_Is_Constant(l2_tn1)) {
06113 l2_val1 = TN_Value(l2_tn1);
06114 l3_tn1 = l2_tn1;
06115 l3_tninfo1 = NULL;
06116 } else return FALSE;
06117
06118 if ((l2_tninfo0 != NULL) &&
06119 (l2_tninfo0->in_op != NULL)) {
06120 l2_op0 = l2_tninfo0->in_op;
06121 l2_opcode0 = OP_code(l2_op0);
06122
06123 if ((l2_opcode0 != TOP_sxt4) &&
06124 (l2_opcode0 != TOP_zxt4)) return FALSE;
06125
06126 l2_opinfo0 = locate_opinfo_entry (l2_tninfo0);
06127 if (l2_opinfo0 == NULL) return FALSE;
06128 if (l2_opinfo0->actual_opnd[1] == NULL) return FALSE;
06129 if (!EBO_tn_available(bb, l2_opinfo0->actual_opnd[1])) return FALSE;
06130
06131 l3_tn0 = OP_opnd(l2_op0,1);
06132 l3_tninfo0 = l2_opinfo0->actual_opnd[1];
06133 } else if (TN_Is_Constant(l2_tn0)) {
06134 l2_val0 = TN_Value(l2_tn0);
06135 l3_tn0 = l2_tn0;
06136 l3_tninfo0 = NULL;
06137 } else return FALSE;
06138
06139
06140 if (TN_Is_Constant(l3_tn0) && TN_Is_Constant(l3_tn1)) return FALSE;
06141
06142
06143 if ((l2_op0 != l2_op1) &&
06144 (!TN_Is_Constant(l3_tn0)) &&
06145 (!TN_Is_Constant(l3_tn1))) return FALSE;
06146
06147
06148 if (TN_Is_Constant(l3_tn0)) {
06149 if ((l2_opcode1 == TOP_sxt4) &&
06150 (SEXT_32(l2_val0) != l2_val0)) return FALSE;
06151 if ((l2_opcode1 == TOP_zxt4) &&
06152 (TRUNC_32(l2_val0) != l2_val0)) return FALSE;
06153 }
06154
06155 if (TN_Is_Constant(l3_tn1)) {
06156 if ((l2_opcode0 == TOP_sxt4) &&
06157 (SEXT_32(l2_val1) != l2_val1)) return FALSE;
06158 if ((l2_opcode0 == TOP_zxt4) &&
06159 (TRUNC_32(l2_val1) != l2_val1)) return FALSE;
06160 }
06161
06162
06163 switch (opcode) {
06164 case TOP_cmp_eq: new_opcode = TOP_cmp4_eq; break;
06165 case TOP_cmp_eq_unc: new_opcode = TOP_cmp4_eq_unc; break;
06166 case TOP_cmp_ne: new_opcode = TOP_cmp4_ne; break;
06167 case TOP_cmp_ne_unc: new_opcode = TOP_cmp4_ne_unc; break;
06168 case TOP_cmp_ge: new_opcode = TOP_cmp4_ge; break;
06169 case TOP_cmp_ge_unc: new_opcode = TOP_cmp4_ge_unc; break;
06170 case TOP_cmp_geu: new_opcode = TOP_cmp4_geu; break;
06171 case TOP_cmp_geu_unc: new_opcode = TOP_cmp4_geu_unc; break;
06172 case TOP_cmp_lt: new_opcode = TOP_cmp4_lt; break;
06173 case TOP_cmp_lt_unc: new_opcode = TOP_cmp4_lt_unc; break;
06174 case TOP_cmp_ltu: new_opcode = TOP_cmp4_ltu; break;
06175 case TOP_cmp_ltu_unc: new_opcode = TOP_cmp4_ltu_unc; break;
06176 case TOP_cmp_gt: new_opcode = TOP_cmp4_gt; break;
06177 case TOP_cmp_gt_unc: new_opcode = TOP_cmp4_gt_unc; break;
06178 case TOP_cmp_gtu: new_opcode = TOP_cmp4_gtu; break;
06179 case TOP_cmp_gtu_unc: new_opcode = TOP_cmp4_gtu_unc; break;
06180 case TOP_cmp_le: new_opcode = TOP_cmp4_le; break;
06181 case TOP_cmp_le_unc: new_opcode = TOP_cmp4_le_unc; break;
06182 case TOP_cmp_leu: new_opcode = TOP_cmp4_leu; break;
06183 case TOP_cmp_leu_unc: new_opcode = TOP_cmp4_leu_unc; break;
06184 case TOP_cmp_i_eq: new_opcode = TOP_cmp4_i_eq; break;
06185 case TOP_cmp_i_eq_unc: new_opcode = TOP_cmp4_i_eq_unc; break;
06186 case TOP_cmp_i_ne: new_opcode = TOP_cmp4_i_ne; break;
06187 case TOP_cmp_i_ne_unc: new_opcode = TOP_cmp4_i_ne_unc; break;
06188 case TOP_cmp_i_ge: new_opcode = TOP_cmp4_i_ge; break;
06189 case TOP_cmp_i_ge_unc: new_opcode = TOP_cmp4_i_ge_unc; break;
06190 case TOP_cmp_i_geu: new_opcode = TOP_cmp4_i_geu; break;
06191 case TOP_cmp_i_geu_unc: new_opcode = TOP_cmp4_i_geu_unc; break;
06192 case TOP_cmp_i_lt: new_opcode = TOP_cmp4_i_lt; break;
06193 case TOP_cmp_i_lt_unc: new_opcode = TOP_cmp4_i_lt_unc; break;
06194 case TOP_cmp_i_ltu: new_opcode = TOP_cmp4_i_ltu; break;
06195 case TOP_cmp_i_ltu_unc: new_opcode = TOP_cmp4_i_ltu_unc; break;
06196 case TOP_cmp_i_gt: new_opcode = TOP_cmp4_i_gt; break;
06197 case TOP_cmp_i_gt_unc: new_opcode = TOP_cmp4_i_gt_unc; break;
06198 case TOP_cmp_i_gtu: new_opcode = TOP_cmp4_i_gtu; break;
06199 case TOP_cmp_i_gtu_unc: new_opcode = TOP_cmp4_i_gtu_unc; break;
06200 case TOP_cmp_i_le: new_opcode = TOP_cmp4_i_le; break;
06201 case TOP_cmp_i_le_unc: new_opcode = TOP_cmp4_i_le_unc; break;
06202 case TOP_cmp_i_leu: new_opcode = TOP_cmp4_i_leu; break;
06203 case TOP_cmp_i_leu_unc: new_opcode = TOP_cmp4_i_leu_unc; break;
06204 }
06205
06206 OPS ops = OPS_EMPTY;
06207 if (EBO_Trace_Optimization) fprintf(TFile,"replace 64 bit compare with 32 bit compare\n");
06208 Build_OP (new_opcode,
06209 OP_result(op,0), OP_result(op,1), OP_opnd(op,OP_PREDICATE_OPND),
06210 l3_tn0, l3_tn1, &ops);
06211 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops), opnd_tninfo[OP_PREDICATE_OPND],
06212 l3_tninfo0, l3_tninfo1);
06213 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
06214 BB_Insert_Ops(bb, op, &ops, FALSE);
06215 return TRUE;
06216 }
06217
06218 return FALSE;
06219 }
06220
06221
06222
06223
06224
06225
06226
06227
06228
06229
06230
06231
06232
06233 static
06234 BOOL
06235 compare_bit (OP *op,
06236 TN **opnd_tn,
06237 EBO_TN_INFO **opnd_tninfo)
06238 {
06239
06240 TOP opcode = OP_code(op);
06241 BB *bb = OP_bb(op);
06242 OP *l1_op0 = op;
06243
06244
06245 TN *l2_tn0;
06246 INT64 l2_val0;
06247 OP *l2_op1;
06248 TN *l2_tn1;
06249 EBO_TN_INFO *l2_tninfo1;
06250 EBO_OP_INFO *l2_opinfo1;
06251
06252
06253 OP *l3_op0;
06254 TN *l3_tn0;
06255 EBO_TN_INFO *l3_tninfo0;
06256 EBO_OP_INFO *l3_opinfo0;
06257 TN *l3_tn1;
06258 EBO_TN_INFO *l3_tninfo1;
06259 EBO_OP_INFO *l3_opinfo1;
06260 INT64 l3_value;
06261
06262
06263 TN *save_tn;
06264
06265
06266 TOP new_opcode = TOP_tbit_z;
06267 TN *r_true = OP_result(op,0);
06268 TN *r_false = OP_result(op,1);
06269 TN *test_word;
06270 EBO_TN_INFO *test_word_tninfo;
06271 INT bit_number;
06272
06273 l2_tn0 = OP_opnd(op,1);
06274 if ((l2_tn0 == NULL) || !TN_Is_Constant(l2_tn0)) return FALSE;
06275 l2_val0 = TN_Value(l2_tn0);
06276 if (l2_val0 != 0) {
06277 if (l2_val0 != 1) return FALSE;
06278
06279
06280 save_tn = r_true;
06281 r_true = r_false;
06282 r_false = save_tn;
06283 }
06284
06285 switch (opcode) {
06286
06287 case TOP_cmp_i_eq_unc:
06288 case TOP_cmp4_i_eq_unc:
06289 new_opcode = TOP_tbit_z_unc;
06290 case TOP_cmp_i_eq:
06291 case TOP_cmp4_i_eq:
06292 break;
06293
06294 case TOP_cmp_i_ne_unc:
06295 case TOP_cmp4_i_ne_unc:
06296 new_opcode = TOP_tbit_z_unc;
06297 case TOP_cmp_i_ne:
06298 case TOP_cmp4_i_ne:
06299 save_tn = r_true;
06300 r_true = r_false;
06301 r_false = save_tn;
06302 break;
06303
06304 default: return FALSE;
06305 }
06306
06307
06308 l2_tn1 = OP_opnd(l1_op0,2);
06309 l2_tninfo1 = opnd_tninfo[2];
06310 if ((l2_tninfo1 == NULL) || (l2_tninfo1->in_op == NULL)) return FALSE;
06311 l2_op1 = l2_tninfo1->in_op;
06312
06313
06314
06315
06316
06317
06318
06319
06320
06321
06322 if ((OP_code(l2_op1) == TOP_and) ||
06323 (OP_code(l2_op1) == TOP_and_i)) {
06324
06325 l2_opinfo1 = locate_opinfo_entry (l2_tninfo1);
06326 if (l2_opinfo1 == NULL) {
06327 return FALSE;
06328 }
06329
06330
06331 if ((l2_opinfo1->optimal_opnd[1] != NULL) &&
06332 (l2_opinfo1->optimal_opnd[1]->replacement_tn != NULL) &&
06333 (TN_Is_Constant(l2_opinfo1->optimal_opnd[1]->replacement_tn))) {
06334 l3_tn0 = l2_opinfo1->optimal_opnd[1]->replacement_tn;
06335 l3_tninfo0 = NULL;
06336 } else {
06337 l3_tn0 = OP_opnd(l2_op1,1);
06338 l3_tninfo0 = l2_opinfo1->actual_opnd[1];
06339 if ((l3_tninfo0 != NULL) &&
06340 (l3_tninfo0->replacement_tn != NULL) &&
06341 (TN_Is_Constant(l3_tninfo0->replacement_tn))) {
06342 l3_tn0 = l3_tninfo0->replacement_tn;
06343 l3_tninfo0 = l3_tninfo0->replacement_tninfo;
06344 }
06345 }
06346 if ((l2_opinfo1->optimal_opnd[2] != NULL) &&
06347 (l2_opinfo1->optimal_opnd[2]->replacement_tn != NULL) &&
06348 (TN_Is_Constant(l2_opinfo1->optimal_opnd[2]->replacement_tn))) {
06349 l3_tn1 = l2_opinfo1->optimal_opnd[2]->replacement_tn;
06350 l3_tninfo1 = NULL;
06351 } else {
06352 l3_tn1 = OP_opnd(l2_op1,2);
06353 l3_tninfo1 = l2_opinfo1->actual_opnd[2];
06354 if ((l3_tninfo1 != NULL) &&
06355 (l3_tninfo1->replacement_tn != NULL) &&
06356 (TN_Is_Constant(l3_tninfo1->replacement_tn))) {
06357 l3_tn1 = l3_tninfo1->replacement_tn;
06358 l3_tninfo1 = l3_tninfo1->replacement_tninfo;
06359 }
06360 }
06361
06362 if ((l3_tn0 != NULL) && TN_Is_Constant(l3_tn0)) {
06363 if ((l3_tninfo1 == NULL) ||
06364 TN_is_symbol(l3_tn0)) {
06365 return FALSE;
06366 }
06367 l3_value = TN_Value(l3_tn0);
06368 l3_tn0 = l3_tn1;
06369 l3_tninfo0 = l3_tninfo1;
06370 } else if ((l3_tn1 != NULL) && TN_Is_Constant(l3_tn1)) {
06371 if ((l3_tninfo0 == NULL) ||
06372 TN_is_symbol(l3_tn1)) {
06373 return FALSE;
06374 }
06375 l3_value = TN_Value(l3_tn1);
06376 } else {
06377 return FALSE;
06378 }
06379
06380 if ((l3_value == 1) &&
06381 (l3_tninfo0 != NULL) &&
06382 (l3_tninfo0->in_op != NULL)) {
06383 OP *l3_op = l3_tninfo0->in_op;
06384 TOP l3_opcode = OP_code(l3_op);
06385
06386 if ((l3_opcode == TOP_shr_i) ||
06387 (l3_opcode == TOP_shr_i_u)) {
06388
06389 l3_opinfo1 = find_opinfo_entry (l3_op);
06390 if ((l3_opinfo1 != NULL) &&
06391 (l3_opinfo1->actual_opnd[1] != NULL) &&
06392 (EBO_tn_available(bb, l3_opinfo1->actual_opnd[1]))) {
06393 l3_tn0 = OP_opnd(l3_op, 1);
06394 l3_tninfo0 = l3_opinfo1->actual_opnd[1];
06395 l3_value = 1 << TN_Value(OP_opnd(l3_op, 2));
06396 }
06397 } else if ((l3_opcode == TOP_extr) ||
06398 (l3_opcode == TOP_extr_u)) {
06399 l3_opinfo1 = find_opinfo_entry (l3_op);
06400 if ((l3_opinfo1 != NULL) &&
06401 (l3_opinfo1->actual_opnd[1] != NULL) &&
06402 (EBO_tn_available(bb, l3_opinfo1->actual_opnd[1])) &&
06403 (EBO_bit_length(l3_op) >= 1)) {
06404 l3_tn0 = OP_opnd(l3_op, 1);
06405 l3_tninfo0 = l3_opinfo1->actual_opnd[1];
06406 l3_value = 1 << TN_Value(OP_opnd(l3_op, 2));
06407 }
06408 }
06409
06410 }
06411
06412
06413 if ((l3_value <= 0) || ((l3_value & (l3_value-1)) != 0)) {
06414 return FALSE;
06415 }
06416
06417
06418 INT64 one= 1;
06419 for (bit_number = 0; bit_number < 64; bit_number++)
06420 {
06421 if ((one << bit_number) == l3_value)
06422 break;
06423 }
06424
06425 test_word = l3_tn0;
06426 test_word_tninfo = l3_tninfo0;
06427 } else if ((OP_code(l2_op1) == TOP_shr_i) &&
06428 (TN_Is_Constant(OP_opnd(l2_op1,2))) &&
06429 (TN_Value(OP_opnd(l2_op1,2)) == 63)) {
06430
06431 l2_opinfo1 = locate_opinfo_entry (l2_tninfo1);
06432 if (l2_opinfo1 == NULL) return FALSE;
06433 if (l2_opinfo1->actual_opnd[1] == NULL) return FALSE;
06434
06435
06436 bit_number = 63;
06437 test_word = OP_opnd(l2_op1,1);
06438 test_word_tninfo = l2_opinfo1->actual_opnd[1];
06439
06440
06441
06442 if ((test_word_tninfo != NULL) &&
06443 (test_word_tninfo->in_op != NULL) &&
06444 (OP_code(test_word_tninfo->in_op) == TOP_shl_i) &&
06445 (TN_Is_Constant(OP_opnd(test_word_tninfo->in_op,2)))) {
06446 l3_op0 = test_word_tninfo->in_op;
06447 l3_opinfo0 = locate_opinfo_entry (test_word_tninfo);
06448 if (l3_opinfo0 != NULL) {
06449
06450 bit_number = 63 - TN_Value(OP_opnd(l3_op0,2));
06451 test_word = OP_opnd(l3_op0,1);
06452 test_word_tninfo = l3_opinfo0->actual_opnd[1];
06453 }
06454 }
06455
06456 } else if (((OP_code(l2_op1) == TOP_extr) ||
06457 (OP_code(l2_op1) == TOP_extr_u)) &&
06458 (EBO_bit_length(l2_op1) == 1) &&
06459 (TN_Is_Constant(OP_opnd(l2_op1,2)))) {
06460
06461 l2_opinfo1 = locate_opinfo_entry (l2_tninfo1);
06462 if (l2_opinfo1 == NULL) return FALSE;
06463 if (l2_opinfo1->actual_opnd[1] == NULL) return FALSE;
06464
06465 bit_number = TN_Value(OP_opnd(l2_op1,2));
06466 test_word = OP_opnd(l2_op1,1);
06467 test_word_tninfo = l2_opinfo1->actual_opnd[1];
06468 } else {
06469 return FALSE;
06470 }
06471
06472
06473 if ((test_word_tninfo->in_op != NULL) &&
06474 ((OP_code(test_word_tninfo->in_op) == TOP_sxt1) ||
06475 (OP_code(test_word_tninfo->in_op) == TOP_sxt2) ||
06476 (OP_code(test_word_tninfo->in_op) == TOP_sxt4) ||
06477 (OP_code(test_word_tninfo->in_op) == TOP_zxt1) ||
06478 (OP_code(test_word_tninfo->in_op) == TOP_zxt2) ||
06479 (OP_code(test_word_tninfo->in_op) == TOP_zxt4))) {
06480 INT l3_length;
06481 l3_op0 = test_word_tninfo->in_op;
06482 l3_length = EBO_bit_length(l3_op0);
06483 l3_opinfo1 = locate_opinfo_entry (test_word_tninfo);
06484
06485 if ((l3_opinfo1 != NULL) &&
06486 (l3_opinfo1->actual_opnd[1] != NULL) &&
06487 (EBO_tn_available (bb, l3_opinfo1->actual_opnd[1]))) {
06488 if (bit_number < l3_length) {
06489 test_word = OP_opnd(l3_op0,1);
06490 test_word_tninfo = l3_opinfo1->actual_opnd[1];
06491 } else if ((OP_code(test_word_tninfo->in_op) == TOP_sxt1) ||
06492 (OP_code(test_word_tninfo->in_op) == TOP_sxt2) ||
06493 (OP_code(test_word_tninfo->in_op) == TOP_sxt4)) {
06494 bit_number = l3_length -1;
06495 test_word = OP_opnd(l3_op0,1);
06496 test_word_tninfo = l3_opinfo1->actual_opnd[1];
06497 } else if ((OP_code(test_word_tninfo->in_op) == TOP_zxt1) ||
06498 (OP_code(test_word_tninfo->in_op) == TOP_zxt2) ||
06499 (OP_code(test_word_tninfo->in_op) == TOP_zxt4)) {
06500 bit_number = 0;
06501 test_word = Zero_TN;
06502 test_word_tninfo = NULL;
06503 }
06504 }
06505 }
06506
06507
06508 if ((test_word_tninfo != NULL) &&
06509 (!EBO_tn_available (bb, test_word_tninfo))) {
06510 return FALSE;
06511 }
06512
06513
06514 OPS ops = OPS_EMPTY;
06515 Build_OP (new_opcode, r_true, r_false, OP_opnd(op,OP_PREDICATE_OPND),
06516 test_word, Gen_Literal_TN(bit_number, 4), &ops);
06517 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
06518 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops), opnd_tninfo[OP_PREDICATE_OPND],
06519 test_word_tninfo, NULL);
06520 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
06521 if (EBO_Trace_Optimization) fprintf(TFile,"Test_Bit created\n");
06522 return TRUE;
06523 }
06524
06525
06526
06527
06528 static
06529 BOOL
06530 copy_simplification (OP *op,
06531 TN **opnd_tn,
06532 EBO_TN_INFO **opnd_tninfo)
06533 {
06534 INT cpix = EBO_Copy_Operand(op);
06535 INT prdix = OP_has_predicate(op) ? OP_PREDICATE_OPND : -1;
06536 TN *tnr;
06537 TN *current_tn;
06538 TN *optimal_tn;
06539 TN *predicate_tn;
06540 INT64 val;
06541 EBO_TN_INFO *tninfo;
06542
06543 if (cpix < 0) return FALSE;
06544 if (prdix < 0) return FALSE;
06545 if (OP_results(op) != 1) return FALSE;
06546
06547 tnr = OP_result(op,0);
06548 current_tn = OP_opnd(op,cpix);
06549 optimal_tn = opnd_tn[cpix];
06550 predicate_tn = opnd_tn[prdix];
06551 tninfo = opnd_tninfo[cpix];
06552
06553
06554 if ( (tninfo != NULL) &&
06555 (tninfo->omega == 0) &&
06556 (tninfo->in_bb != NULL) &&
06557 (tnr == current_tn) &&
06558 !has_assigned_reg(tnr) &&
06559 !TN_is_save_reg(tnr) &&
06560 !TN_Is_Constant(current_tn) &&
06561 !has_assigned_reg(current_tn) &&
06562 !TN_is_save_reg(current_tn) ) {
06563
06564 if (EBO_Trace_Optimization) fprintf(TFile,"Copy to self is not needed\n");
06565 if (!TN_is_global_reg(current_tn) && (OP_bb(op) != tninfo->in_bb)) {
06566 mark_tn_live_into_BB (current_tn, OP_bb(op), tninfo->in_bb);
06567 }
06568 return TRUE;
06569 }
06570
06571 if ((TN_register_class(tnr) == ISA_REGISTER_CLASS_integer) &&
06572 (TN_has_value(optimal_tn)) &&
06573 (TN_value(optimal_tn) == 0)) {
06574 OP *new_op;
06575 new_op = Mk_OP(TOP_mov, tnr, predicate_tn, Zero_TN);
06576 OP_srcpos(new_op) = OP_srcpos(op);
06577 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND], NULL );
06578 BB_Insert_Op_After(OP_bb(op), op, new_op);
06579 if (EBO_Trace_Optimization) fprintf(TFile,"Use Zero_TN in place of immediate constant\n");
06580 return TRUE;
06581 }
06582
06583
06584
06585
06586
06587
06588
06589 EBO_TN_INFO *predicate_tninfo = opnd_tninfo[OP_PREDICATE_OPND];
06590 if ((predicate_tninfo != NULL) &&
06591 (predicate_tninfo->in_op != NULL) &&
06592 (!TN_Is_Constant(predicate_tn))) {
06593
06594 INT op1_idx = 1;
06595 TN *tnr = OP_result(op,0);
06596 EBO_TN_INFO *previous_tninfo = get_tn_info(tnr);
06597 EBO_OP_INFO *previous_opinfo = NULL;
06598 EBO_TN_INFO *previous_op0_tninfo = NULL;
06599 TOP previous_opcode = TOP_noop;
06600 if ((previous_tninfo != NULL) &&
06601 (previous_tninfo->in_op != NULL) &&
06602 (previous_tninfo->reference_count == 0) &&
06603 (previous_tninfo->predicate_tninfo != NULL)) {
06604 previous_opinfo = locate_opinfo_entry (previous_tninfo);
06605 if ((previous_opinfo != NULL) &&
06606 (previous_opinfo->in_op != NULL)) {
06607 previous_opcode = OP_code(previous_opinfo->in_op);
06608 previous_op0_tninfo = previous_opinfo->optimal_opnd[op1_idx];
06609 }
06610 }
06611 if ((previous_op0_tninfo != NULL) &&
06612 (previous_opcode == TOP_fneg) &&
06613 (opnd_tn[op1_idx] == previous_op0_tninfo->local_tn) &&
06614 EBO_predicate_complements (predicate_tn, predicate_tninfo,
06615 previous_tninfo->predicate_tninfo->local_tn, previous_tninfo->predicate_tninfo)) {
06616 OP *predicate_op = predicate_tninfo->in_op;
06617 TOP predicate_opcode = OP_code(predicate_op);
06618 EBO_OP_INFO *predicate_opinfo = locate_opinfo_entry (predicate_tninfo);
06619 if ((predicate_opinfo != NULL) &&
06620 (predicate_opinfo->in_op != NULL) &&
06621 EBO_tn_available(OP_bb(op), predicate_opinfo->actual_opnd[OP_PREDICATE_OPND]) &&
06622 (((predicate_opcode == TOP_fcmp_lt_unc) || (predicate_opcode == TOP_fcmp_le_unc)) &&
06623 (predicate_opinfo->actual_rslt[1] == predicate_tninfo) &&
06624 (OP_opnd(predicate_op, TOP_Find_Operand_Use(predicate_opcode,OU_opnd2)) == FZero_TN) &&
06625 (predicate_opinfo->optimal_opnd[TOP_Find_Operand_Use(predicate_opcode,OU_opnd1)] == opnd_tninfo[op1_idx]))) {
06626 if (EBO_Trace_Optimization) fprintf(TFile,"simplify fneg(fcmp()) operation.\n");
06627 BB *bb = OP_bb(op);
06628 TOP new_opcode = TOP_fmerge_s;
06629 OP *new_op = Mk_OP (new_opcode, tnr,
06630 OP_opnd(predicate_op,OP_PREDICATE_OPND), FZero_TN, OP_opnd(op,1));
06631 OP_srcpos(new_op) = OP_srcpos(op);
06632 if (EBO_in_loop) EBO_Set_OP_omega ( new_op,
06633 predicate_opinfo->actual_opnd[OP_PREDICATE_OPND],
06634 opnd_tninfo[op1_idx]);
06635 BB_Insert_Op_After(bb, op, new_op);
06636
06637
06638 remove_op (previous_opinfo);
06639 OP_Change_To_Noop(previous_opinfo->in_op);
06640 previous_opinfo->in_op = NULL;
06641 previous_opinfo->in_bb = NULL;
06642 return TRUE;
06643 }
06644 } else if ((previous_tninfo != NULL) &&
06645 (previous_tninfo->predicate_tninfo != NULL) &&
06646 (previous_opinfo != NULL) &&
06647 (previous_opinfo->in_op != NULL) &&
06648 OP_effectively_copy(previous_opinfo->in_op) &&
06649 EBO_predicate_complements (predicate_tn, predicate_tninfo,
06650 previous_tninfo->predicate_tninfo->local_tn, previous_tninfo->predicate_tninfo) &&
06651 (((previous_op0_tninfo != NULL) &&
06652 (opnd_tn[op1_idx] == previous_op0_tninfo->local_tn)) ||
06653 (TN_Is_Constant(current_tn) &&
06654 (current_tn == OP_opnd(previous_opinfo->in_op,EBO_Copy_Operand(previous_opinfo->in_op)))))) {
06655 OP *predicate_op = predicate_tninfo->in_op;
06656 TOP predicate_opcode = OP_code(predicate_op);
06657 EBO_OP_INFO *predicate_opinfo = locate_opinfo_entry (predicate_tninfo);
06658 if ((predicate_opinfo != NULL) &&
06659 (predicate_opinfo->in_op != NULL) &&
06660 OP_icmp(predicate_opinfo->in_op) &&
06661 EBO_tn_available(OP_bb(op), predicate_opinfo->actual_opnd[OP_PREDICATE_OPND]) &&
06662 TNs_Are_Equivalent(current_tn, OP_opnd(previous_opinfo->in_op,EBO_Copy_Operand(previous_opinfo->in_op)))) {
06663 if (EBO_Trace_Optimization) fprintf(TFile,"complementary moves of the same value\n");
06664 OPS ops = OPS_EMPTY;
06665 TN * predicate_tn = OP_opnd(predicate_opinfo->in_op,OP_PREDICATE_OPND);
06666 EBO_Exp_COPY (predicate_tn,
06667 OP_result(op, 0),
06668 current_tn,
06669 &ops);
06670 OP_srcpos(OPS_first(&ops)) = OP_srcpos(op);
06671 if (EBO_in_loop) EBO_Set_OP_omega (OPS_first(&ops), predicate_opinfo->actual_opnd[OP_PREDICATE_OPND],
06672 previous_opinfo->actual_opnd[EBO_Copy_Operand(previous_opinfo->in_op)]);
06673 if (predicate_tn != True_TN) Set_OP_cond_def_kind(OPS_last(&ops), OP_PREDICATED_DEF);
06674 BB_Insert_Ops(OP_bb(op), op, &ops, FALSE);
06675 return TRUE;
06676 }
06677 }
06678 }
06679
06680 if (current_tn == optimal_tn) return FALSE;
06681 if (TN_is_const_reg(current_tn)) return FALSE;
06682 if ((predicate_tn == True_TN) ||
06683 (predicate_tn == Zero_TN) ||
06684 TN_is_constant(predicate_tn)) return FALSE;
06685 if (TN_register_class(tnr) != ISA_REGISTER_CLASS_integer) return FALSE;
06686 if (!TN_has_value(optimal_tn)) return FALSE;
06687
06688
06689 val = TN_value(optimal_tn);
06690 OP *new_op;
06691 TOP new_opcode = (ISA_LC_Value_In_Class (val, LC_i22)) ? TOP_mov_i : TOP_movl;
06692 new_op = Mk_OP(new_opcode, tnr, predicate_tn, optimal_tn);
06693 OP_srcpos(new_op) = OP_srcpos(op);
06694 if (EBO_in_loop) EBO_Set_OP_omega ( new_op, opnd_tninfo[OP_PREDICATE_OPND], NULL );
06695 BB_Insert_Op_After(OP_bb(op), op, new_op);
06696 if (EBO_Trace_Optimization) fprintf(TFile,"Conditionally load an immediate constant\n");
06697 return TRUE;
06698 }
06699
06700
06701
06702
06703
06704
06705
06706
06707
06708
06709
06710
06711
06712
06713
06714
06715
06716
06717
06718
06719
06720
06721
06722 BOOL Process_Group_Register_Reference (OP *op)
06723 {
06724 REGISTER i;
06725 REGISTER first;
06726 REGISTER last;
06727 TN *pred_tn;
06728
06729 switch (OP_code(op)) {
06730 case TOP_clrrrb:
06731 first = REGISTER_First_Rotating_Registers(ISA_REGISTER_CLASS_integer);
06732 last = REGISTER_Last_Rotating_Registers (ISA_REGISTER_CLASS_integer);
06733
06734 for (i=first; i<=last; i++) {
06735 TN *tn = Build_Dedicated_TN(ISA_REGISTER_CLASS_integer,i,0);
06736 EBO_TN_INFO *tninfo = get_tn_info(tn);
06737 if (tninfo != NULL) {
06738 if(EBO_Trace_Optimization)fprintf(TFile,"TOP_clrrrb r%d\n",i);
06739 EBO_TN_INFO *new_tninfo = tn_info_def (OP_bb(op), op, tn, True_TN, NULL);
06740 inc_ref_count(tninfo);
06741 }
06742 }
06743
06744 first = REGISTER_First_Rotating_Registers(ISA_REGISTER_CLASS_float);
06745 last = REGISTER_Last_Rotating_Registers (ISA_REGISTER_CLASS_float);
06746
06747 for (i=first; i<=last; i++) {
06748 TN *tn = Build_Dedicated_TN(ISA_REGISTER_CLASS_float,i,0);
06749 EBO_TN_INFO *tninfo = get_tn_info(tn);
06750 if (tninfo != NULL) {
06751 if(EBO_Trace_Optimization)fprintf(TFile,"TOP_clrrrb f%d\n",i);
06752 EBO_TN_INFO *new_tninfo = tn_info_def (OP_bb(op), op, tn, True_TN, NULL);
06753 inc_ref_count(tninfo);
06754 }
06755 }
06756
06757
06758 case TOP_clrrrb_pr:
06759 first = REGISTER_First_Rotating_Registers(ISA_REGISTER_CLASS_predicate);
06760 last = REGISTER_Last_Rotating_Registers (ISA_REGISTER_CLASS_predicate);
06761
06762 for (i=first; i<=last; i++) {
06763 TN *tn = Build_Dedicated_TN(ISA_REGISTER_CLASS_predicate,i,0);
06764 EBO_TN_INFO *tninfo = get_tn_info(tn);
06765 if (tninfo != NULL) {
06766 if(EBO_Trace_Optimization)fprintf(TFile,"TOP_clrrrb pr%d\n",i);
06767 EBO_TN_INFO *new_tninfo = tn_info_def (OP_bb(op), op, tn, True_TN, NULL);
06768 inc_ref_count(tninfo);
06769 }
06770 }
06771
06772 return TRUE;
06773 case TOP_mov_t_pr_i:
06774 first = REGISTER_First_Rotating_Registers(ISA_REGISTER_CLASS_predicate);
06775 last = REGISTER_Last_Rotating_Registers (ISA_REGISTER_CLASS_predicate);
06776 pred_tn = OP_has_predicate(op)?OP_opnd(op,OP_PREDICATE_OPND):True_TN;
06777
06778 for (i=first; i<=last; i++) {
06779 TN *tn = Build_Dedicated_TN(ISA_REGISTER_CLASS_predicate,i,0);
06780 EBO_TN_INFO *tninfo = get_tn_info(tn);
06781 if (tninfo != NULL) {
06782 if(EBO_Trace_Optimization)fprintf(TFile,"TOP_mov_t_pr_i pr%d\n",i);
06783 EBO_TN_INFO *new_tninfo = tn_info_def (OP_bb(op), op, tn, pred_tn, NULL);
06784 inc_ref_count(tninfo);
06785 }
06786 }
06787
06788 return TRUE;
06789 case TOP_mov_t_pr:
06790 first = REGISTER_MIN + 1;
06791 last = REGISTER_CLASS_last_register (ISA_REGISTER_CLASS_predicate);
06792 pred_tn = OP_has_predicate(op)?OP_opnd(op,OP_PREDICATE_OPND):True_TN;
06793
06794 for (i=first; i<=last; i++) {
06795 TN *tn = Build_Dedicated_TN(ISA_REGISTER_CLASS_predicate,i,0);
06796 EBO_TN_INFO *tninfo = get_tn_info(tn);
06797 if (tninfo != NULL) {
06798 if(EBO_Trace_Optimization)fprintf(TFile,"TOP_mov_t_pr pr%d\n",i);
06799 EBO_TN_INFO *new_tninfo = tn_info_def (OP_bb(op), op, tn, pred_tn, NULL);
06800 inc_ref_count(tninfo);
06801 }
06802 }
06803
06804 return TRUE;
06805 case TOP_mov_f_pr:
06806 first = REGISTER_MIN + 1;
06807 last = REGISTER_CLASS_last_register (ISA_REGISTER_CLASS_predicate);
06808 pred_tn = OP_has_predicate(op)?OP_opnd(op,OP_PREDICATE_OPND):True_TN;
06809
06810 for (i=first; i<=last; i++) {
06811 TN *tn = Build_Dedicated_TN(ISA_REGISTER_CLASS_predicate,i,0);
06812 EBO_TN_INFO *tninfo = get_tn_info(tn);
06813 if (tninfo != NULL) {
06814 if(EBO_Trace_Optimization)fprintf(TFile,"TOP_mov_f_pr pr%d\n",i);
06815 inc_ref_count(tninfo);
06816 }
06817 }
06818
06819 return TRUE;
06820 }
06821
06822 return FALSE;
06823 }
06824
06825
06826
06827
06828
06829
06830
06831
06832
06833 BOOL Special_Sequence (OP *op,
06834 TN **opnd_tn,
06835 EBO_TN_INFO **opnd_tninfo)
06836 {
06837 TOP opcode = OP_code(op);
06838
06839 if (OP_iadd(op)) {
06840 return (shl_add_sequence ( op, opnd_tn, opnd_tninfo) ||
06841 iadd_special_case( op, opnd_tn, opnd_tninfo));
06842 }
06843 if (OP_store(op)) {
06844 return (store_sequence( op, opnd_tn, opnd_tninfo) ||
06845 sxt_sequence ( op, TOP_Find_Operand_Use(OP_code(op),OU_storeval),
06846 opnd_tn, opnd_tninfo));
06847 }
06848 if (OP_fadd(op)) {
06849 return (fadd_fmult (op, opnd_tninfo));
06850 }
06851 if (OP_fsub(op)) {
06852 return (fadd_fmult (op, opnd_tninfo));
06853 }
06854 if ((opcode == TOP_fneg) ||
06855 (opcode == TOP_fpneg)) {
06856 return (fneg_sequence (op, opnd_tn, opnd_tninfo));
06857 }
06858 if (OP_icmp(op)) {
06859 return (condition_optimization (op, opnd_tn, opnd_tninfo) ||
06860 compare_bit (op, opnd_tn, opnd_tninfo) ||
06861 sxt_sequence (op, TOP_Find_Operand_Use(OP_code(op),OU_opnd1),
06862 opnd_tn, opnd_tninfo) ||
06863 sxt_sequence (op, TOP_Find_Operand_Use(OP_code(op),OU_opnd2),
06864 opnd_tn, opnd_tninfo));
06865 }
06866 if ((opcode == TOP_sxt1) ||
06867 (opcode == TOP_sxt2) ||
06868 (opcode == TOP_sxt4) ||
06869 (opcode == TOP_zxt1) ||
06870 (opcode == TOP_zxt2) ||
06871 (opcode == TOP_zxt4) ||
06872 (opcode == TOP_dep) ||
06873 (opcode == TOP_dep_z) ||
06874 (opcode == TOP_extr) ||
06875 (opcode == TOP_extr_u) ||
06876 (opcode == TOP_shr_i) ||
06877 (opcode == TOP_shr_i_u)) {
06878 return (sxt_sequence (op, 1, opnd_tn, opnd_tninfo));
06879 }
06880 if (opcode == TOP_and_i) {
06881 return (sxt_sequence (op, 2, opnd_tn, opnd_tninfo));
06882 }
06883 if ((opcode == TOP_setf_sig) ||
06884 (opcode == TOP_getf_sig)) {
06885 return (copy_rf_sequence (op, opnd_tn, opnd_tninfo));
06886 }
06887 if (OP_effectively_copy(op)) {
06888 return (copy_simplification (op, opnd_tn, opnd_tninfo));
06889 }
06890 if (OP_access_reg_bank(op)) {
06891 return Process_Group_Register_Reference (op);
06892 }
06893 return FALSE;
06894 }