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 #if defined(BACK_END) && defined(WN_SIMP_WORKING_ON_WHIRL)
00036 #include "be_symtab.h"
00037 #endif
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 #define SIMP_TYPE_SIZE(x) MTYPE_size_min(x)
00147
00148
00149
00150 #define SIMP_IS_TYPE_INTEGRAL(x) ((MTYPE_type_class(x)&MTYPE_CLASS_INTEGER)!=0)
00151 #define SIMP_IS_TYPE_UNSIGNED(x) ((MTYPE_type_class(x)&MTYPE_CLASS_UNSIGNED)!=0)
00152 #define SIMP_IS_TYPE_FLOATING(x) ((MTYPE_type_class(x)&MTYPE_CLASS_FLOAT)!=0)
00153 #define SIMP_IS_TYPE_COMPLEX(x) ((MTYPE_type_class(x)&MTYPE_CLASS_COMPLEX)!=0)
00154
00155
00156 #define OPC_FROM_OPR(opr,type) (OPCODE_make_op(opr,type,MTYPE_V))
00157
00158
00159 static BOOL SIMPNODE_simp_initialized = FALSE;
00160 static void SIMPNODE_Simplify_Initialize( void );
00161
00162
00163
00164 static BOOL trace_trees;
00165 #define SHOW_TREE(opc,k0,k1,result) if ((result!=NULL) && trace_trees) show_tree(opc,k0,k1,result)
00166
00167
00168
00169 static BOOL trace_rules;
00170
00171 #define SHOW_RULE(x) show_rule(x)
00172
00173 static void show_rule(const char * rule)
00174 {
00175 if (trace_rules) {
00176 fprintf(TRACEFILE,"Rule: %s\n",rule);
00177 }
00178 }
00179
00180
00181
00182 static simpnode SIMPNODE_ConstantFold1(OPCODE opc, simpnode k0);
00183 static simpnode SIMPNODE_ConstantFold2(OPCODE opc, simpnode k0, simpnode k1);
00184 static simpnode SIMPNODE_SimpCreateExp3(OPCODE opc, simpnode k0, simpnode k1, simpnode k2);
00185 static simpnode SIMPNODE_SimpCreateExp2(OPCODE opc, simpnode k0, simpnode k1);
00186 static simpnode SIMPNODE_SimpCreateExp1(OPCODE opc, simpnode k0);
00187 static simpnode SIMPNODE_SimpCreateExtract(OPCODE opc, INT16 boffset, INT16 bsize, simpnode k0);
00188 static simpnode SIMPNODE_SimpCreateDeposit(OPCODE opc, INT16 boffset, INT16 bsize,
00189 simpnode k0, simpnode k1);
00190
00191 #ifdef SIMPNODE_SimpCreateCvtl
00192 static simpnode SIMPNODE_SimpCreateCvtl(OPCODE opc, INT16 bits, simpnode k0);
00193 #endif
00194
00195
00196
00197
00198 #define SIMP_INTCONST(ty,value) SIMPNODE_CreateIntconst(OPC_FROM_OPR(OPR_INTCONST,ty),(value))
00199
00200
00201 #define SIMP_FLOATCONST(ty,value) SIMPNODE_CreateFloatconstFromTcon(Host_To_Targ_Float(ty,(value)))
00202
00203
00204 static void simp_delete_tree(simpnode w)
00205 {
00206 if (!trace_trees) SIMPNODE_TREE_DELETE(w);
00207 }
00208
00209 static void simp_delete(simpnode w)
00210 {
00211 if (!trace_trees) SIMPNODE_DELETE(w);
00212 }
00213
00214 #define SIMP_DELETE(x) simp_delete(x)
00215 #define SIMP_DELETE_TREE(x) simp_delete_tree(x)
00216
00217 #define SIMP_TYPE(x) SIMPNODE_rtype(x)
00218
00219 inline simpnode SIMPNODE_GetDefinition(simpnode x)
00220 {
00221 #ifdef BACK_END
00222 #ifdef WN_SIMP_WORKING_ON_WHIRL
00223 if (SIMPNODE_operator(x) == OPR_LDID && ST_class(WN_st(x)) == CLASS_PREG) {
00224 WN *home = Preg_Home(WN_load_offset(x));
00225 if (home) x = home;
00226 }
00227 #else
00228
00229 #endif
00230 #endif
00231 return x;
00232 }
00233
00234
00235
00236 inline BOOL SIMP_Is_Int_Constant(simpnode x)
00237 {
00238 return SIMPNODE_operator(x)==OPR_INTCONST;
00239 }
00240
00241 inline BOOL SIMP_Is_Flt_Constant(simpnode x)
00242 {
00243 x = SIMPNODE_GetDefinition(x);
00244 return SIMPNODE_operator(x)==OPR_CONST;
00245 }
00246
00247 inline BOOL SIMP_Is_Constant(simpnode x)
00248 {
00249 x = SIMPNODE_GetDefinition(x);
00250 return SIMPNODE_operator(x)==OPR_INTCONST
00251 || SIMPNODE_operator(x)==OPR_CONST;
00252 }
00253
00254
00255
00256
00257 inline INT64 SIMP_Int_ConstVal(simpnode x)
00258 {
00259 x = SIMPNODE_GetDefinition(x);
00260 return SIMPNODE_const_val(x);
00261 }
00262
00263 inline TCON SIMP_Flt_ConstVal(simpnode x)
00264 {
00265 x = SIMPNODE_GetDefinition(x);
00266 return SIMPNODE_fconst_val(x);
00267 }
00268
00269
00270 #define IS_POWER_OF_2(x) (((x)!=0) && ((x) & ((x)-1))==0)
00271
00272
00273
00274 static INT64 create_bitmask(INT64 num_bits)
00275 {
00276 if (num_bits == 0) return (0);
00277 if (num_bits == 64) return (-1LL);
00278 return ((1LL << num_bits) - 1);
00279 }
00280
00281
00282
00283 namespace wn_simp_code {
00284
00285
00286
00287 static UINT64 log2(UINT64 x)
00288 {
00289 UINT64 l;
00290
00291 l = 0;
00292 while (x > 1) {
00293 x >>= 1;
00294 ++l;
00295 }
00296 return (l);
00297 }
00298 }
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 static BOOL is_add_ok(INT64 *sum, INT64 i1, INT64 i2, TYPE_ID ty)
00310 {
00311 *sum = i1 + i2;
00312
00313 switch (ty) {
00314 case MTYPE_U4:
00315 if ((UINT64) *sum > UINT32_MAX) return(FALSE);
00316 break;
00317
00318 case MTYPE_I4:
00319 if (*sum > INT32_MAX) return(FALSE);
00320 if (*sum < INT32_MIN) return(FALSE);
00321 break;
00322
00323 case MTYPE_U8:
00324 if ((UINT64) *sum < (UINT64) i1) return (FALSE);
00325 break;
00326
00327 case MTYPE_I8:
00328 if ((i1^i2) < 0) return (TRUE);
00329
00330 if ((i1 > 0 || i2 > 0) && *sum <= 0) return (FALSE);
00331 if ((i1 < 0 || i2 < 0) && *sum >= 0) return (FALSE);
00332 break;
00333
00334 default:
00335
00336 return (FALSE);
00337 }
00338
00339 return (TRUE);
00340 }
00341
00342 static BOOL is_sub_ok(INT64 *sum, INT64 i1, INT64 i2, TYPE_ID ty)
00343 {
00344 *sum = i1 - i2;
00345
00346 switch (ty) {
00347
00348 case MTYPE_I4:
00349 if (*sum > INT32_MAX) return(FALSE);
00350 if (*sum < INT32_MIN) return(FALSE);
00351 break;
00352
00353 case MTYPE_U4:
00354 case MTYPE_U8:
00355 if ((UINT64) i2 > (UINT64) i1) return FALSE;
00356 break;
00357
00358 case MTYPE_I8:
00359 if ((i1^i2) >= 0) return (TRUE);
00360
00361 if ((i1 > i2) && *sum <= 0) return (FALSE);
00362 if ((i1 < i2) && *sum >= 0) return (FALSE);
00363 break;
00364
00365 default:
00366
00367 return (FALSE);
00368 }
00369
00370 return (TRUE);
00371 }
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382 static BOOL is_floating_equal(simpnode k, double d)
00383 {
00384 TCON kval,dval;
00385 INT64 eqval;
00386 TYPE_ID ty;
00387
00388 if (!SIMP_Is_Constant(k)) return (FALSE);
00389 ty = SIMPNODE_rtype(k);
00390 if (SIMP_IS_TYPE_INTEGRAL(ty) || SIMP_IS_TYPE_COMPLEX(ty)) return (FALSE);
00391
00392 kval = SIMP_Flt_ConstVal(k);
00393
00394 switch (ty) {
00395 case MTYPE_F4:
00396 case MTYPE_F8:
00397 return (d == Targ_To_Host_Float(kval));
00398
00399 case MTYPE_FQ:
00400
00401 dval = Host_To_Targ_Float(MTYPE_FQ, d);
00402 eqval = Targ_To_Host(Targ_WhirlOp(OPC_I4FQEQ,dval,kval,NULL));
00403 return (eqval != 0);
00404 }
00405 return (FALSE);
00406 }
00407
00408
00409
00410
00411
00412
00413
00414
00415 static BOOL is_numeric_equal(simpnode k, double d)
00416 {
00417 INT64 c;
00418 UINT64 uc;
00419 TYPE_ID ty;
00420
00421 if (!SIMP_Is_Constant(k)) return (FALSE);
00422 ty = SIMPNODE_rtype(k);
00423 if (SIMP_IS_TYPE_COMPLEX(ty)) return (FALSE);
00424 if (SIMP_IS_TYPE_FLOATING(ty)) return (is_floating_equal(k,d));
00425 if (SIMP_IS_TYPE_UNSIGNED(ty)) {
00426 uc = (UINT64) SIMP_Int_ConstVal(k);
00427 return (uc == d);
00428 } else if (SIMP_IS_TYPE_INTEGRAL(ty)) {
00429 c = SIMP_Int_ConstVal(k);
00430 return (c == d);
00431 }
00432 return (FALSE);
00433 }
00434
00435
00436
00437
00438
00439
00440
00441 #define LDA_CANNOT_BE_ZERO 1 // Address of symbol cannot be 0
00442 #define LDA_EQUIV_POSSIBLE 2 // Might have same address as another symbol
00443 #define LDA_UNTESTABLE 4 // Can't figure out anything about the symbol
00444 typedef INT LDA_FLAGS;
00445
00446 static LDA_FLAGS get_lda_info(simpnode lda, INT64& offset, ST_IDX& base_sym_idx)
00447 {
00448 ST_IDX base_idx=SIMPNODE_st_idx(lda);
00449 ST *base;
00450 LDA_FLAGS r = 0;
00451
00452 base = ST_ptr(base_idx);
00453 offset = SIMPNODE_lda_offset(lda);
00454
00455 while ( base && (ST_sclass(base) != SCLASS_TEXT) && (ST_base(base) != base)) {
00456 offset += ST_ofst(base);
00457 base = ST_base(base);
00458 }
00459
00460
00461
00462
00463 if (!base) {
00464 return (LDA_UNTESTABLE | LDA_CANNOT_BE_ZERO | LDA_EQUIV_POSSIBLE);
00465 }
00466
00467 offset += ST_ofst(base);
00468 base_sym_idx = ST_st_idx(*base);
00469
00470 if ((ST_export(base) != EXPORT_PREEMPTIBLE) &&
00471 (ST_export(base) != EXPORT_OPTIONAL) &&
00472 (ST_sclass(base) != SCLASS_FORMAL_REF) &&
00473 (ST_sclass(base) != SCLASS_EXTERN) &&
00474 !ST_is_weak_symbol(base)) {
00475 r |= LDA_CANNOT_BE_ZERO;
00476 }
00477
00478 if (ST_export(base) == EXPORT_PREEMPTIBLE ||
00479 ST_sclass(base) == SCLASS_EXTERN ||
00480 ST_sclass(base) == SCLASS_COMMON ||
00481 ST_sclass(base) == SCLASS_MODULE ||
00482 ST_is_weak_symbol(base)) {
00483 r |= LDA_EQUIV_POSSIBLE;
00484 }
00485
00486 return (r);
00487 }
00488
00489 typedef enum {
00490 NO,YES,MAYBE
00491 } YESNOMAYBE;
00492
00493
00494 static YESNOMAYBE LDA_Equal_Address (simpnode lda_x,simpnode lda_y)
00495 {
00496 const ST *x;
00497 const ST *y;
00498 LDA_FLAGS fx,fy;
00499 INT64 x_offset,y_offset;
00500 ST_IDX x_base_sym_idx,y_base_sym_idx;
00501
00502 fx = get_lda_info(lda_x, x_offset, x_base_sym_idx);
00503 fy = get_lda_info(lda_y, y_offset, y_base_sym_idx);
00504
00505 if (((fx|fy)&LDA_UNTESTABLE)!=0) return MAYBE;
00506 if (x_base_sym_idx == y_base_sym_idx) {
00507 if (x_offset == y_offset) return YES;
00508 return NO;
00509 }
00510
00511 if (x_offset != y_offset) return MAYBE;
00512
00513 x = ST_ptr(x_base_sym_idx);
00514 y = ST_ptr(y_base_sym_idx);
00515
00516
00517
00518 BOOL x_maybe_weak = (ST_is_weak_symbol (x) ||
00519 (ST_sclass (x) == SCLASS_EXTERN &&
00520 ST_export (x) == EXPORT_PREEMPTIBLE));
00521 BOOL y_maybe_weak = (ST_is_weak_symbol (y) ||
00522 (ST_sclass (y) == SCLASS_EXTERN &&
00523 ST_export (y) == EXPORT_PREEMPTIBLE));
00524
00525
00526
00527
00528
00529
00530 BOOL maybe_aliased =
00531 (ST_is_weak_symbol (x) && ST_strong_idx (*x) == ST_st_idx (y)) ||
00532 (ST_is_weak_symbol (y) && ST_strong_idx (*y) == ST_st_idx (x)) ||
00533 (ST_export (x) == EXPORT_OPTIONAL) ||
00534 (ST_export (y) == EXPORT_OPTIONAL) ||
00535 (x_maybe_weak && y_maybe_weak);
00536
00537 if (!maybe_aliased) return NO;
00538 else return MAYBE;
00539 }
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565 INT32 SIMPNODE_Simp_Compare_Trees(simpnode t1, simpnode t2)
00566 {
00567 INT32 i;
00568 INT32 rv;
00569
00570
00571
00572
00573 if (t1 == t2) return (0);
00574
00575
00576 if (SIMPNODE_opcode(t1) < SIMPNODE_opcode(t2))
00577 return (-1);
00578 else if (SIMPNODE_opcode(t1) > SIMPNODE_opcode(t2))
00579 return (1);
00580
00581
00582 switch (SIMPNODE_operator(t1)) {
00583 case OPR_INTCONST:
00584 if (SIMPNODE_const_val(t1) < SIMPNODE_const_val(t2)) return(-1);
00585 if (SIMPNODE_const_val(t1) > SIMPNODE_const_val(t2)) return(1);
00586 return (0);
00587
00588 case OPR_CVTL:
00589 if (SIMPNODE_cvtl_bits(t1) < SIMPNODE_cvtl_bits(t2)) return (-1);
00590 if (SIMPNODE_cvtl_bits(t1) > SIMPNODE_cvtl_bits(t2)) return (1);
00591 return (SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid0(t1),
00592 SIMPNODE_kid0(t2)));
00593
00594
00595 case OPR_EXTRACT_BITS:
00596 if (SIMPNODE_op_bit_offset(t1) < SIMPNODE_op_bit_offset(t2)) return (-1);
00597 if (SIMPNODE_op_bit_offset(t1) > SIMPNODE_op_bit_offset(t2)) return (1);
00598 if (SIMPNODE_op_bit_size(t1) < SIMPNODE_op_bit_size(t2)) return (-1);
00599 if (SIMPNODE_op_bit_size(t1) > SIMPNODE_op_bit_size(t2)) return (1);
00600 return (SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid0(t1),
00601 SIMPNODE_kid0(t2)));
00602
00603
00604 case OPR_COMPOSE_BITS:
00605 if (SIMPNODE_op_bit_offset(t1) < SIMPNODE_op_bit_offset(t2)) return (-1);
00606 if (SIMPNODE_op_bit_offset(t1) > SIMPNODE_op_bit_offset(t2)) return (1);
00607 if (SIMPNODE_op_bit_size(t1) < SIMPNODE_op_bit_size(t2)) return (-1);
00608 if (SIMPNODE_op_bit_size(t1) > SIMPNODE_op_bit_size(t2)) return (1);
00609 rv = SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid0(t1), SIMPNODE_kid0(t2));
00610 if (rv == 0) {
00611 rv = SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid1(t1), SIMPNODE_kid1(t2));
00612 }
00613 return rv;
00614
00615
00616 case OPR_CONST:
00617 return SIMPNODE_Compare_Symbols(t1,t2);
00618
00619 case OPR_ILOAD:
00620 if (SIMPNODE_load_offset(t1) < SIMPNODE_load_offset(t2)) return(-1);
00621 if (SIMPNODE_load_offset(t1) > SIMPNODE_load_offset(t2)) return(1);
00622 if (SIMPNODE_desc(t1) == MTYPE_BS || SIMPNODE_desc(t2) == MTYPE_BS) {
00623 if (SIMPNODE_i_field_id(t1) < SIMPNODE_i_field_id(t2)) return(-1);
00624 if (SIMPNODE_i_field_id(t1) > SIMPNODE_i_field_id(t2)) return(1);
00625 }
00626 return (SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid0(t1),
00627 SIMPNODE_kid0(t2)));
00628
00629 case OPR_ILDBITS:
00630 if (SIMPNODE_load_offset(t1) < SIMPNODE_load_offset(t2)) return(-1);
00631 if (SIMPNODE_load_offset(t1) > SIMPNODE_load_offset(t2)) return(1);
00632 if (SIMPNODE_i_bit_offset(t1) < SIMPNODE_i_bit_offset(t2)) return(-1);
00633 if (SIMPNODE_i_bit_offset(t1) > SIMPNODE_i_bit_offset(t2)) return(1);
00634 return (SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid0(t1),
00635 SIMPNODE_kid0(t2)));
00636
00637 case OPR_MLOAD:
00638 case OPR_ILOADX:
00639 if (SIMPNODE_load_offset(t1) < SIMPNODE_load_offset(t2)) return(-1);
00640 if (SIMPNODE_load_offset(t1) > SIMPNODE_load_offset(t2)) return(1);
00641 rv = SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid0(t1),SIMPNODE_kid0(t2));
00642 if (rv != 0) return (rv);
00643 return (SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid1(t1),
00644 SIMPNODE_kid1(t2)));
00645
00646 case OPR_LDID:
00647 if (SIMPNODE_load_offset(t1) < SIMPNODE_load_offset(t2)) return(-1);
00648 if (SIMPNODE_load_offset(t1) > SIMPNODE_load_offset(t2)) return(1);
00649 if (SIMPNODE_desc(t1) == MTYPE_BS || SIMPNODE_desc(t2) == MTYPE_BS) {
00650 if (SIMPNODE_field_id(t1) < SIMPNODE_field_id(t2)) return(-1);
00651 if (SIMPNODE_field_id(t1) > SIMPNODE_field_id(t2)) return(1);
00652 }
00653 return SIMPNODE_Compare_Symbols(t1,t2);
00654
00655 case OPR_LDBITS:
00656 if (SIMPNODE_load_offset(t1) < SIMPNODE_load_offset(t2)) return(-1);
00657 if (SIMPNODE_load_offset(t1) > SIMPNODE_load_offset(t2)) return(1);
00658 if (SIMPNODE_bit_offset(t1) < SIMPNODE_bit_offset(t2)) return(-1);
00659 if (SIMPNODE_bit_offset(t1) > SIMPNODE_bit_offset(t2)) return(1);
00660 return SIMPNODE_Compare_Symbols(t1,t2);
00661
00662 case OPR_IDNAME:
00663 if (SIMPNODE_idname_offset(t1) < SIMPNODE_idname_offset(t2)) return(-1);
00664 if (SIMPNODE_idname_offset(t1) > SIMPNODE_idname_offset(t2)) return(1);
00665 return SIMPNODE_Compare_Symbols(t1,t2);
00666
00667 case OPR_LDA:
00668 if (SIMPNODE_lda_offset(t1) < SIMPNODE_lda_offset(t2)) return(-1);
00669 if (SIMPNODE_lda_offset(t1) > SIMPNODE_lda_offset(t2)) return(1);
00670 return SIMPNODE_Compare_Symbols(t1,t2);
00671
00672 case OPR_ARRAY:
00673 if (SIMPNODE_num_dim(t1) < SIMPNODE_num_dim(t2)) return (-1);
00674 if (SIMPNODE_num_dim(t1) > SIMPNODE_num_dim(t2)) return (1);
00675 if (SIMPNODE_element_size(t1) < SIMPNODE_element_size(t2)) return (-1);
00676 if (SIMPNODE_element_size(t1) > SIMPNODE_element_size(t2)) return (1);
00677
00678 rv = SIMPNODE_Simp_Compare_Trees(SIMPNODE_array_base(t1),
00679 SIMPNODE_array_base(t2));
00680 if (rv != 0) return (rv);
00681
00682
00683 for (i=0; i < SIMPNODE_num_dim(t1); i++) {
00684 rv = SIMPNODE_Simp_Compare_Trees(SIMPNODE_array_index(t1,i),
00685 SIMPNODE_array_index(t2,i));
00686 if (rv != 0) return (rv);
00687 rv = SIMPNODE_Simp_Compare_Trees(SIMPNODE_array_dim(t1,i),
00688 SIMPNODE_array_dim(t2,i));
00689 if (rv != 0) return (rv);
00690 }
00691
00692 return (0);
00693
00694 case OPR_INTRINSIC_OP:
00695 if (SIMPNODE_intrinsic(t1) < SIMPNODE_intrinsic(t2)) return (-1);
00696 if (SIMPNODE_intrinsic(t1) > SIMPNODE_intrinsic(t2)) return (1);
00697 if (SIMPNODE_kid_count(t1) < SIMPNODE_kid_count(t2)) return (-1);
00698 if (SIMPNODE_kid_count(t1) > SIMPNODE_kid_count(t2)) return (1);
00699
00700 for (i=0; i<SIMPNODE_kid_count(t1); i++) {
00701 rv = SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid(t1,i),
00702 SIMPNODE_kid(t2,i));
00703 if (rv != 0) return (rv);
00704 }
00705 return (0);
00706
00707 case OPR_COMMA:
00708 case OPR_RCOMMA:
00709 case OPR_CSELECT:
00710
00711 return ((INTPS)t1 - (INTPS)t2);
00712
00713 default:
00714 if (OPCODE_is_expression(SIMPNODE_opcode(t1))) {
00715 for (i=0; i<SIMPNODE_kid_count(t1); i++) {
00716 rv = SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid(t1,i),
00717 SIMPNODE_kid(t2,i));
00718 if (rv != 0) return (rv);
00719 }
00720 return (0);
00721 } else {
00722
00723 return ((INTPS)t1 - (INTPS)t2);
00724 }
00725 }
00726 }
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739 static OPCODE is_logop(OPCODE opc)
00740 {
00741 OPERATOR op;
00742
00743 op = OPCODE_operator(opc);
00744 if (op == OPR_LAND || op == OPR_LIOR) return (opc);
00745 return OPCODE_UNKNOWN;
00746 }
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762 static BOOL is_ok_to_reassociate(OPCODE opc)
00763 {
00764 switch (OPCODE_operator(opc)) {
00765 case OPR_MAX:
00766 case OPR_MIN:
00767 case OPR_BAND:
00768 case OPR_BIOR:
00769 case OPR_BXOR:
00770 case OPR_LAND:
00771 case OPR_LIOR:
00772 return (TRUE);
00773
00774 case OPR_ADD:
00775 case OPR_MPY:
00776 if (SIMP_IS_TYPE_INTEGRAL(OPCODE_rtype(opc))) {
00777 return (TRUE);
00778 #ifdef __FP_REASSOCIATE__
00779 } else if (SIMP_IS_TYPE_FLOATING(OPCODE_rtype(opc))) {
00780 return (Enable_Cfold_Reassociate);
00781 #endif
00782 } else {
00783
00784 return (FALSE);
00785 }
00786
00787 default:
00788 return (FALSE);
00789 }
00790 }
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803 static OPCODE get_inverse_relop( OPCODE opc )
00804 {
00805 OPCODE iopc;
00806 OPERATOR iopr;
00807
00808 switch (OPCODE_operator(opc)) {
00809 case OPR_LT: iopr = OPR_GE; break;
00810 case OPR_LE: iopr = OPR_GT; break;
00811 case OPR_GT: iopr = OPR_LE; break;
00812 case OPR_GE: iopr = OPR_LT; break;
00813 case OPR_EQ: iopr = OPR_NE; break;
00814 case OPR_NE: iopr = OPR_EQ; break;
00815 default: return OPCODE_UNKNOWN;
00816 }
00817
00818 iopc = OPCODE_make_op(iopr, OPCODE_rtype(opc), OPCODE_desc(opc));
00819 return iopc;
00820 }
00821
00822
00823
00824
00825
00826
00827 static TYPE_ID get_value_type(simpnode k0)
00828 {
00829 TYPE_ID ty;
00830 OPERATOR op;
00831 op = SIMPNODE_operator(k0);
00832 if (op == OPR_ILOAD || op == OPR_LDID || op == OPR_LDBITS) {
00833 ty = OPCODE_desc(SIMPNODE_opcode(k0));
00834 } else {
00835 ty = SIMPNODE_rtype(k0);
00836 }
00837 return (ty);
00838 }
00839
00840
00841
00842
00843
00844 static simpnode simp_diff_value(simpnode k0, simpnode k1, BOOL negate_result)
00845 {
00846 INT64 resultval;
00847 simpnode r;
00848 TYPE_ID ty;
00849
00850 r = NULL;
00851
00852 if (SIMPNODE_operator(k0) == OPR_LDA &&
00853 SIMPNODE_operator(k1) == OPR_LDA &&
00854 SIMPNODE_Compare_Symbols(k0,k1) == 0) {
00855 resultval = SIMPNODE_lda_offset(k0) - SIMPNODE_lda_offset(k1);
00856 if (negate_result) resultval = -resultval;
00857 if (SIMPNODE_rtype(k0) == MTYPE_U4) {
00858 r = SIMP_INTCONST(MTYPE_I4,resultval);
00859 } else {
00860 r = SIMP_INTCONST(MTYPE_I8,resultval);
00861 }
00862 } else if (SIMPNODE_Simp_Compare_Trees(k0,k1) == 0) {
00863 ty = SIMPNODE_rtype(k0);
00864 if (SIMP_IS_TYPE_FLOATING(ty)) {
00865 r = SIMP_FLOATCONST(ty,0.0);
00866 } else {
00867 r = SIMP_INTCONST(ty,0);
00868 }
00869 }
00870 return (r);
00871 }
00872
00873 #define FACTOR_11 1
00874 #define FACTOR_12 2
00875 #define FACTOR_21 4
00876 #define FACTOR_22 8
00877 #define FACTOR_ALL (FACTOR_11 | FACTOR_12 | FACTOR_21 | FACTOR_22)
00878 #define FACTOR_OK(flag,type) ((flag&type)!=0)
00879
00880
00881
00882
00883
00884
00885
00886 static simpnode simp_factor (simpnode k0, simpnode k1, OPERATOR op1,
00887 OPCODE opc2, TYPE_ID ty, INT32 flag)
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900 {
00901 simpnode r = NULL;
00902 OPCODE opc1;
00903
00904 if (!Enable_Cfold_Aggressive ||
00905 (!Enable_Cfold_Reassociate && SIMP_IS_TYPE_FLOATING(ty))) return (r);
00906 opc1 = OPC_FROM_OPR(op1,ty);
00907 if (SIMPNODE_opcode(k0) == opc1 &&
00908 SIMPNODE_opcode(k1) == opc1) {
00909
00910
00911 if (FACTOR_OK(flag,FACTOR_11) &&
00912 SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid0(k0),SIMPNODE_kid0(k1))==0) {
00913 SHOW_RULE("z*x op z*y");
00914 r = SIMPNODE_SimpCreateExp2(opc1,SIMPNODE_kid0(k0),
00915 SIMPNODE_SimpCreateExp2(opc2,SIMPNODE_kid1(k0),
00916 SIMPNODE_kid1(k1)));
00917 SIMP_DELETE_TREE(SIMPNODE_kid0(k1));
00918 SIMP_DELETE(k0);
00919 SIMP_DELETE(k1);
00920
00921 } else if (FACTOR_OK(flag,FACTOR_22) &&
00922 SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid1(k0),SIMPNODE_kid1(k1))==0) {
00923 SHOW_RULE("x*z op y*z");
00924 r = SIMPNODE_SimpCreateExp2(opc1, SIMPNODE_SimpCreateExp2(opc2,SIMPNODE_kid0(k0),
00925 SIMPNODE_kid0(k1)),
00926 SIMPNODE_kid1(k0));
00927 SIMP_DELETE_TREE(SIMPNODE_kid1(k1));
00928 SIMP_DELETE(k0);
00929 SIMP_DELETE(k1);
00930
00931 } else if (FACTOR_OK(flag,FACTOR_21) &&
00932 SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid1(k0),SIMPNODE_kid0(k1))==0) {
00933 SHOW_RULE("x*z op z*y");
00934 r = SIMPNODE_SimpCreateExp2(opc1,SIMPNODE_kid1(k0),
00935 SIMPNODE_SimpCreateExp2(opc2,SIMPNODE_kid0(k0),
00936 SIMPNODE_kid1(k1)));
00937 SIMP_DELETE_TREE(SIMPNODE_kid0(k1));
00938 SIMP_DELETE(k0);
00939 SIMP_DELETE(k1);
00940 } else if (FACTOR_OK(flag,FACTOR_12) &&
00941 SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid0(k0),SIMPNODE_kid1(k1))==0) {
00942 SHOW_RULE("z*x op y*z");
00943 r = SIMPNODE_SimpCreateExp2(opc1,SIMPNODE_kid0(k0),
00944 SIMPNODE_SimpCreateExp2(opc2,SIMPNODE_kid1(k0),
00945 SIMPNODE_kid0(k1)));
00946 SIMP_DELETE_TREE(SIMPNODE_kid1(k1));
00947 SIMP_DELETE(k0);
00948 SIMP_DELETE(k1);
00949 }
00950 }
00951 return (r);
00952
00953 }
00954
00955
00956
00957 static simpnode make_identity(OPERATOR opr,TYPE_ID ty)
00958 {
00959 simpnode r = NULL;
00960 switch (opr) {
00961 case OPR_ADD:
00962 case OPR_SUB:
00963 case OPR_BIOR:
00964 case OPR_BXOR:
00965 case OPR_LIOR:
00966 if (SIMP_IS_TYPE_FLOATING(ty)) {
00967 r = SIMP_FLOATCONST(ty,0.0);
00968 } else {
00969 r = SIMP_INTCONST(ty,0);
00970 }
00971 break;
00972
00973 case OPR_MPY:
00974 case OPR_LAND:
00975 if (SIMP_IS_TYPE_FLOATING(ty)) {
00976 r = SIMP_FLOATCONST(ty,1.0);
00977 } else {
00978 r = SIMP_INTCONST(ty,1);
00979 }
00980 break;
00981 case OPR_BAND:
00982 r = SIMP_INTCONST(ty,-1);
00983 break;
00984 default:
00985 FmtAssert(FALSE,
00986 ("unknown identity value requested in simplifier"));
00987
00988 }
00989 return (r);
00990 }
00991
00992 static simpnode simp_factor_idty (simpnode k0, simpnode k1, OPERATOR op1,
00993 OPCODE opc2, TYPE_ID ty, INT32 const_only)
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007 {
01008 simpnode r = NULL;
01009 OPCODE opc1;
01010
01011 if (!Enable_Cfold_Aggressive ||
01012 (!Enable_Cfold_Reassociate && SIMP_IS_TYPE_FLOATING(ty))) return (r);
01013
01014 opc1 = OPC_FROM_OPR(op1,ty);
01015 if (SIMPNODE_opcode(k0) == opc1) {
01016
01017 if (SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid0(k0),k1)==0) {
01018 if (!const_only || SIMP_Is_Constant(SIMPNODE_kid1(k0))) {
01019 SHOW_RULE("z*x op z");
01020 r = SIMPNODE_SimpCreateExp2(opc1,SIMPNODE_kid0(k0),
01021 SIMPNODE_SimpCreateExp2(opc2,SIMPNODE_kid1(k0),
01022 make_identity(op1,ty)));
01023 SIMP_DELETE(k0);
01024 SIMP_DELETE_TREE(k1);
01025 }
01026 } else if (SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid1(k0),k1)==0) {
01027 if (!const_only || SIMP_Is_Constant(SIMPNODE_kid0(k0))) {
01028 SHOW_RULE("x*z op z");
01029 r = SIMPNODE_SimpCreateExp2(opc1, SIMPNODE_SimpCreateExp2(opc2,SIMPNODE_kid0(k0),
01030 make_identity(op1,ty)),
01031 SIMPNODE_kid1(k0));
01032 SIMP_DELETE(k0);
01033 SIMP_DELETE_TREE(k1);
01034 }
01035 }
01036 } else if (SIMPNODE_opcode(k1) == opc1) {
01037 if (SIMPNODE_Simp_Compare_Trees(k0,SIMPNODE_kid0(k1))==0) {
01038 if (!const_only || SIMP_Is_Constant(SIMPNODE_kid1(k1))) {
01039 SHOW_RULE("z op z*y");
01040 r = SIMPNODE_SimpCreateExp2(opc1,SIMPNODE_kid0(k1),
01041 SIMPNODE_SimpCreateExp2(opc2,make_identity(op1,ty),
01042 SIMPNODE_kid1(k1)));
01043
01044 SIMP_DELETE_TREE(k0);
01045 SIMP_DELETE(k1);
01046 }
01047 } else if (SIMPNODE_Simp_Compare_Trees(k0,SIMPNODE_kid1(k1))==0) {
01048 if (!const_only || SIMP_Is_Constant(SIMPNODE_kid0(k1))) {
01049 SHOW_RULE("z op y*z");
01050 r = SIMPNODE_SimpCreateExp2(opc1,SIMPNODE_SimpCreateExp2(opc2,make_identity(op1,ty),
01051 SIMPNODE_kid0(k1)),
01052 SIMPNODE_kid1(k1));
01053 SIMP_DELETE_TREE(k0);
01054 SIMP_DELETE(k1);
01055 }
01056 }
01057 }
01058 return (r);
01059 }
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088 static simpnode simp_abs(OPCODE opc, simpnode k0, simpnode k1,
01089 BOOL k0const, BOOL k1const)
01090 {
01091 simpnode r = NULL;
01092 OPERATOR opr;
01093 TYPE_ID sty,dty;
01094 OPCODE cvt_op,abs_op;
01095
01096 opr = SIMPNODE_operator(k0);
01097 if (opr == OPR_ABS) {
01098 SHOW_RULE("ABS(ABS(x)) -> ABS(X)");
01099 r = k0;
01100 } else if (opr == OPR_NEG) {
01101 SHOW_RULE("ABS(-x) -> ABS(x)");
01102 r = SIMPNODE_SimpCreateExp1(opc,SIMPNODE_kid0(k0));
01103 SIMP_DELETE(k0);
01104 } else if (opr == OPR_CVT) {
01105 cvt_op = SIMPNODE_opcode(k0);
01106 sty = OPCODE_desc(cvt_op);
01107 dty = OPCODE_rtype(cvt_op);
01108 if (dty == OPCODE_rtype(opc) &&
01109 SIMP_IS_TYPE_FLOATING(sty) && !SIMP_IS_TYPE_COMPLEX(sty)) {
01110 SHOW_RULE("ABS(CVT) -> CVT(ABS)");
01111 abs_op = OPC_FROM_OPR(OPR_ABS,sty);
01112 r = SIMPNODE_SimpCreateExp1(abs_op,SIMPNODE_kid0(k0));
01113 r = SIMPNODE_SimpCreateExp1(cvt_op,r);
01114 SIMP_DELETE(k0);
01115 }
01116 }
01117
01118 return (r);
01119 }
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134 static simpnode simp_not(OPCODE opc, simpnode k0, simpnode k1,
01135 BOOL k0const, BOOL k1const)
01136 {
01137 simpnode r = NULL;
01138 OPCODE inverse_relop;
01139
01140 if (opc == SIMPNODE_opcode(k0)) {
01141 SHOW_RULE("~ ~ j -> j");
01142 r = SIMPNODE_kid0(k0);
01143 SIMP_DELETE(k0);
01144 } else if (SIMPNODE_operator(k0) == OPR_BIOR && OPCODE_operator(opc) == OPR_BNOT &&
01145 ARCH_generate_nor) {
01146 SHOW_RULE("~(a | b) -> a nor b");
01147 r = SIMPNODE_SimpCreateExp2(OPC_FROM_OPR(OPR_BNOR,OPCODE_rtype(opc)),
01148 SIMPNODE_kid0(k0),SIMPNODE_kid1(k0));
01149 SIMP_DELETE(k0);
01150 } else if (SIMPNODE_operator(k0) == OPR_BNOR && OPCODE_operator(opc) == OPR_BNOT) {
01151 SHOW_RULE("~(a nor b) -> a | b");
01152 r = SIMPNODE_SimpCreateExp2(OPC_FROM_OPR(OPR_BIOR,OPCODE_rtype(opc)),
01153 SIMPNODE_kid0(k0),SIMPNODE_kid1(k0));
01154 SIMP_DELETE(k0);
01155 } else {
01156 inverse_relop = get_inverse_relop(SIMPNODE_opcode(k0));
01157
01158
01159 if ((opc == OPC_I4LNOT || opc == OPC_BLNOT) && inverse_relop != 0 &&
01160
01161 (! (Force_IEEE_Comparisons &&
01162 SIMP_IS_TYPE_FLOATING(OPCODE_desc(inverse_relop)))))
01163 {
01164 SHOW_RULE("! <relop>");
01165 inverse_relop = OPCODE_make_op(OPCODE_operator(inverse_relop),
01166 OPCODE_rtype(opc),
01167 OPCODE_desc(inverse_relop));
01168 r = SIMPNODE_SimpCreateExp2(inverse_relop,SIMPNODE_kid0(k0),SIMPNODE_kid1(k0));
01169 SIMP_DELETE(k0);
01170 }
01171 }
01172
01173 return (r);
01174 }
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188 static simpnode simp_neg(OPCODE opc, simpnode k0, simpnode k1,
01189 BOOL k0const, BOOL k1const)
01190 {
01191 simpnode r = NULL;
01192 TYPE_ID ty;
01193
01194 ty = SIMPNODE_rtype(k0);
01195
01196 if (opc == SIMPNODE_opcode(k0)) {
01197 SHOW_RULE("-(-x)");
01198 r = SIMPNODE_kid0(k0);
01199 SIMP_DELETE(k0);
01200
01201 } else if (SIMPNODE_operator(k0) == OPR_SUB) {
01202 SHOW_RULE("-(x-y)");
01203 r = SIMPNODE_SimpCreateExp2(SIMPNODE_opcode(k0),SIMPNODE_kid1(k0),
01204 SIMPNODE_kid0(k0));
01205 SIMP_DELETE(k0);
01206 } else if (((SIMPNODE_operator(k0) == OPR_MPY) || (SIMPNODE_operator(k0) == OPR_DIV)) &&
01207 SIMP_Is_Constant(SIMPNODE_kid1(k0)) && !SIMP_IS_TYPE_UNSIGNED(ty)) {
01208 SHOW_RULE(" - x*/c");
01209 ty = SIMPNODE_rtype(SIMPNODE_kid1(k0));
01210 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_NEG,ty),SIMPNODE_kid1(k0));
01211 r = SIMPNODE_SimpCreateExp2(SIMPNODE_opcode(k0),SIMPNODE_kid0(k0),r);
01212 SIMP_DELETE(k0);
01213 } else if (SIMPNODE_operator(k0) == OPR_DIV &&
01214 SIMP_Is_Constant(SIMPNODE_kid0(k0)) && !SIMP_IS_TYPE_UNSIGNED(ty)) {
01215 SHOW_RULE(" - c/x");
01216 ty = SIMPNODE_rtype(SIMPNODE_kid0(k0));
01217 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_NEG,ty),SIMPNODE_kid0(k0));
01218 r = SIMPNODE_SimpCreateExp2(SIMPNODE_opcode(k0),r,SIMPNODE_kid1(k0));
01219 SIMP_DELETE(k0);
01220 }
01221
01222
01223 return (r);
01224 }
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240 static simpnode simp_recip(OPCODE opc, simpnode k0, simpnode k1,
01241 BOOL k0const, BOOL k1const)
01242 {
01243 simpnode r = NULL;
01244 OPERATOR op,child_op;
01245 TYPE_ID ty;
01246
01247 op = OPCODE_operator(opc);
01248 child_op = SIMPNODE_operator(k0);
01249 ty = OPCODE_rtype(opc);
01250
01251 if (op == OPR_RECIP) {
01252 switch (child_op) {
01253 case OPR_RECIP:
01254 SHOW_RULE("RECIP(RECIP(X))");
01255 if (Roundoff_Level >= ROUNDOFF_SIMPLE) {
01256 r = SIMPNODE_kid0(k0);
01257 SIMP_DELETE(k0);
01258 }
01259 break;
01260
01261 case OPR_SQRT:
01262 SHOW_RULE(" RECIP(SQRT(x)) RSQRT(x) ");
01263 if (Rsqrt_Allowed) {
01264 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_RSQRT,ty),SIMPNODE_kid0(k0));
01265 SIMP_DELETE(k0);
01266 }
01267 break;
01268
01269 case OPR_RSQRT:
01270 SHOW_RULE(" RECIP(RSQRT(x)) SQRT(x) ");
01271 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_SQRT,ty),SIMPNODE_kid0(k0));
01272 SIMP_DELETE(k0);
01273 break;
01274
01275 default:
01276 break;
01277 }
01278 } else if (op == OPR_SQRT && child_op == OPR_RECIP &&
01279 Rsqrt_Allowed) {
01280 SHOW_RULE(" SQRT(RECIP(x)) RSQRT(x) ");
01281 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_RSQRT,ty),SIMPNODE_kid0(k0));
01282 SIMP_DELETE(k0);
01283 } else if (op == OPR_RSQRT && child_op == OPR_RECIP) {
01284 SHOW_RULE(" RSQRT(RECIP(x)) SQRT(x) ");
01285 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_SQRT,ty),SIMPNODE_kid0(k0));
01286 SIMP_DELETE(k0);
01287 }
01288
01289 return (r);
01290 }
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315 #define B(t) (1<<t)
01316 #define PRECISE_I1 B(MTYPE_F4)|B(MTYPE_F8)|B(MTYPE_FQ)|B(MTYPE_I1)|B(MTYPE_I2)|B(MTYPE_I4)|B(MTYPE_I8)
01317 #define PRECISE_I2 B(MTYPE_F4)|B(MTYPE_F8)|B(MTYPE_FQ)|B(MTYPE_I2)|B(MTYPE_I4)|B(MTYPE_I8)
01318 #define PRECISE_I4 B(MTYPE_F8)|B(MTYPE_FQ)|B(MTYPE_I4)|B(MTYPE_I8)
01319 #define PRECISE_I8 B(MTYPE_FQ)|B(MTYPE_I8)
01320 #define PRECISE_U1 B(MTYPE_F4)|B(MTYPE_F8)|B(MTYPE_FQ)|B(MTYPE_U1)|B(MTYPE_U2)|B(MTYPE_U4)|B(MTYPE_U8)
01321 #define PRECISE_U2 B(MTYPE_F4)|B(MTYPE_F8)|B(MTYPE_FQ)|B(MTYPE_U2)|B(MTYPE_U4)|B(MTYPE_U8)
01322 #define PRECISE_U4 B(MTYPE_F8)|B(MTYPE_FQ)|B(MTYPE_I8)
01323 #define PRECISE_U8 B(MTYPE_FQ)
01324 #define PRECISE_F4 B(MTYPE_F4)|B(MTYPE_F8)|B(MTYPE_FQ)
01325 #define PRECISE_F8 B(MTYPE_F8)|B(MTYPE_FQ)
01326 #define PRECISE_FQ B(MTYPE_FQ)
01327 #define TESTABLE_TYPE (B(MTYPE_U1)|B(MTYPE_U2)|B(MTYPE_U4)|B(MTYPE_U8)|\
01328 B(MTYPE_I1)|B(MTYPE_I2)|B(MTYPE_I4)|B(MTYPE_I8)|\
01329 B(MTYPE_F4)|B(MTYPE_F8)|B(MTYPE_FQ))
01330 #define TYPEISIN(t,b) ( ((1<<(t)) & (b)) !=0)
01331
01332 static BOOL convert_precise(TYPE_ID t1, TYPE_ID t2)
01333 {
01334 BOOL r = FALSE;
01335 INT32 precise_bits;
01336
01337 if (TYPEISIN(t1,TESTABLE_TYPE) && TYPEISIN(t2,TESTABLE_TYPE)) {
01338 switch (t1) {
01339 case MTYPE_U1:
01340 precise_bits = PRECISE_U1;
01341 break;
01342 case MTYPE_U2:
01343 precise_bits = PRECISE_U2;
01344 break;
01345 case MTYPE_U4:
01346 precise_bits = PRECISE_U4;
01347 break;
01348 case MTYPE_U8:
01349 precise_bits = PRECISE_U8;
01350 break;
01351 case MTYPE_I1:
01352 precise_bits = PRECISE_I1;
01353 break;
01354 case MTYPE_I2:
01355 precise_bits = PRECISE_I2;
01356 break;
01357 case MTYPE_I4:
01358 precise_bits = PRECISE_I4;
01359 break;
01360 case MTYPE_I8:
01361 precise_bits = PRECISE_I8;
01362 break;
01363 case MTYPE_F4:
01364 precise_bits = PRECISE_F4;
01365 break;
01366 case MTYPE_F8:
01367 precise_bits = PRECISE_F8;
01368 break;
01369 case MTYPE_FQ:
01370 precise_bits = PRECISE_FQ;
01371 break;
01372 default:
01373 precise_bits = 0;
01374 break;
01375 }
01376 r = TYPEISIN(t2,precise_bits);
01377 }
01378 return (r);
01379 }
01380
01381
01382
01383
01384 static simpnode simp_cvt(OPCODE opc, simpnode k0, simpnode k1,
01385 BOOL k0const, BOOL k1const)
01386 {
01387 simpnode r = NULL;
01388 simpnode k0k0;
01389 OPCODE k0opc,newopc;
01390 OPERATOR op, k0op;
01391 TYPE_ID source_type, dest_type, inter_type,source_value_type;
01392
01393 op = OPCODE_operator(opc);
01394 k0opc = SIMPNODE_opcode(k0);
01395 k0op = OPCODE_operator(k0opc);
01396
01397 if (OPCODE_desc(k0opc) == MTYPE_BS)
01398 return (NULL);
01399
01400 #ifdef WN_SIMP_WORKING_ON_WHIRL
01401
01402 if (!WHIRL_Keep_Cvt_On) {
01403 if (opc == OPC_I8I4CVT || opc == OPC_U8I4CVT) {
01404 SHOW_RULE("Removed CVT");
01405 return (k0);
01406 }
01407 }
01408
01409
01410
01411 if (op == OPR_CVT &&
01412 (k0op == OPR_LDID || k0op == OPR_ILOAD) &&
01413 !WN_Is_Volatile_Mem(k0)) {
01414 source_type = OPCODE_desc(k0opc);
01415 inter_type = OPCODE_rtype(k0opc);
01416 dest_type = OPCODE_rtype(opc);
01417 if (OPCODE_rtype(k0opc) == OPCODE_desc(opc) &&
01418 (SIMP_IS_TYPE_UNSIGNED(source_type))==(SIMP_IS_TYPE_UNSIGNED(dest_type))) {
01419
01420
01421 if (Is_Valid_Opcode_Parts(k0op,dest_type,source_type)) {
01422 newopc = OPCODE_make_op(k0op,dest_type,source_type);
01423 } else {
01424 newopc = OPCODE_UNKNOWN;
01425 }
01426 if (k0op == OPR_LDID && ST_class(WN_st(k0))==CLASS_PREG) {
01427 newopc = OPCODE_UNKNOWN;
01428 }
01429
01430 if (newopc != OPCODE_UNKNOWN) {
01431 SHOW_RULE("CVT(LOAD)");
01432 WN_set_opcode(k0,newopc);
01433 return (k0);
01434 }
01435 }
01436 }
01437 #endif
01438
01439 #ifndef EMULATE_LONGLONG
01440
01441
01442 if (opc == OPC_U4I8CVT || opc == OPC_U4U8CVT) {
01443 if ((k0op == OPR_BAND && SIMP_Is_Constant(SIMPNODE_kid1(k0))
01444 && (UINT64) SIMP_Int_ConstVal(SIMPNODE_kid1(k0)) <= 0x7fffffff) ||
01445 (k0op == OPR_LSHR && SIMP_Is_Constant(SIMPNODE_kid1(k0))
01446 && SIMP_Int_ConstVal(SIMPNODE_kid1(k0)) >= 33)) {
01447 SHOW_RULE("Removed U4I8/U4U8CVT");
01448 return (k0);
01449 }
01450 } else if (opc == OPC_I4I8CVT || opc == OPC_I4U8CVT) {
01451 if ((k0op == OPR_ASHR && SIMP_Is_Constant(SIMPNODE_kid1(k0))
01452 && SIMP_Int_ConstVal(SIMPNODE_kid1(k0)) >= 32) ||
01453 (k0op == OPR_BAND && SIMP_Is_Constant(SIMPNODE_kid1(k0))
01454 && (UINT64) SIMP_Int_ConstVal(SIMPNODE_kid1(k0)) <= 0x7fffffff) ||
01455 (k0op == OPR_LSHR && SIMP_Is_Constant(SIMPNODE_kid1(k0))
01456 && SIMP_Int_ConstVal(SIMPNODE_kid1(k0)) >= 33)) {
01457 SHOW_RULE("Removed I4I8/I4U8CVT");
01458 return (k0);
01459 }
01460 }
01461
01462 #endif
01463
01464
01465 if (op == OPR_REALPART &&
01466 k0op == OPR_COMPLEX) {
01467 SHOW_RULE(" REALPART (COMPLEX(a,b)) a ");
01468 r = SIMPNODE_kid0(k0);
01469 SIMP_DELETE_TREE(SIMPNODE_kid1(k0));
01470 SIMP_DELETE(k0);
01471 return (r);
01472
01473 } if (op == OPR_IMAGPART &&
01474 k0op == OPR_COMPLEX) {
01475 SHOW_RULE(" IMAGPART (COMPLEX(a,b)) b ");
01476 r = SIMPNODE_kid1(k0);
01477 SIMP_DELETE_TREE(SIMPNODE_kid0(k0));
01478 SIMP_DELETE(k0);
01479 return (r);
01480 }
01481
01482 if (op == OPR_CVT &&
01483 k0op == OPR_CVT) {
01484 source_type = OPCODE_desc(k0opc);
01485 inter_type = OPCODE_rtype(k0opc);
01486 dest_type = OPCODE_rtype(opc);
01487 k0k0 = SIMPNODE_kid0(k0);
01488 source_value_type = get_value_type(k0k0);
01489
01490 if (convert_precise(source_value_type,inter_type)) {
01491 if (Is_Valid_Opcode_Parts(OPR_CVT,dest_type,source_type)) {
01492 newopc = OPCODE_make_op(OPR_CVT,dest_type,source_type);
01493 } else {
01494 newopc = OPCODE_UNKNOWN;
01495 }
01496 if (newopc != OPCODE_UNKNOWN) {
01497 SHOW_RULE("t1CVT(t2CVT(a)) -> t1CVT(a)");
01498 r = SIMPNODE_SimpCreateExp1(newopc,k0k0);
01499 SIMP_DELETE(k0);
01500 } else if (source_type == dest_type) {
01501 SHOW_RULE("t1CVT(t2CVT(a)) -> a");
01502 r = k0k0;
01503 SIMP_DELETE(k0);
01504 }
01505 }
01506 }
01507
01508 if (op == OPR_TRUNC &&
01509 k0op == OPR_CVT) {
01510 source_type = OPCODE_desc(k0opc);
01511 inter_type = OPCODE_rtype(k0opc);
01512 dest_type = OPCODE_rtype(opc);
01513 k0k0 = SIMPNODE_kid0(k0);
01514 source_value_type = get_value_type(k0k0);
01515 if (convert_precise(source_value_type,inter_type)) {
01516 if (Is_Valid_Opcode_Parts(OPR_TRUNC,dest_type,source_type)) {
01517 newopc = OPCODE_make_op(OPR_TRUNC,dest_type,source_type);
01518 } else {
01519 newopc = OPCODE_UNKNOWN;
01520 }
01521 if (newopc != OPCODE_UNKNOWN) {
01522 SHOW_RULE("t1TRUNC(t2CVT(a)) -> t1TRUNC(a)");
01523 r = SIMPNODE_SimpCreateExp1(newopc,k0k0);
01524 SIMP_DELETE(k0);
01525 } else if (source_type == dest_type) {
01526 SHOW_RULE("t1TRUNC(t2CVT(a)) -> a");
01527 r = k0k0;
01528 SIMP_DELETE(k0);
01529 } else {
01530 if (Is_Valid_Opcode_Parts(OPR_CVT,dest_type,source_type)) {
01531 newopc = OPCODE_make_op(OPR_CVT,dest_type,source_type);
01532 SHOW_RULE("t1TRUNC(t2CVT(a)) -> t1CVT(a)");
01533 r = SIMPNODE_SimpCreateExp1(newopc,k0k0);
01534 SIMP_DELETE(k0);
01535 }
01536 }
01537 }
01538 }
01539
01540
01541 if (op == OPR_TAS &&
01542 OPCODE_rtype(opc) == OPCODE_rtype(k0opc)) {
01543 r = k0;
01544 return (r);
01545 }
01546
01547
01548 return (r);
01549 }
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616 #define SELECT_ADD_SUB(x) ((x)? subop : addop)
01617
01618 static simpnode simp_add_sub(OPCODE opc,
01619 simpnode k0, simpnode k1, BOOL k0const, BOOL k1const)
01620 {
01621 simpnode r = NULL;
01622 BOOL reassoc, issub;
01623 TYPE_ID ty;
01624 OPCODE subop,addop,negop;
01625 simpnode x[4], t, dt;
01626 BOOL s[4], bt, constant_moved;
01627 INT32 num_const,num_ops,i,j,k,ic1,ic2,d1,d2;
01628
01629 ty = OPCODE_rtype(opc);
01630 issub = (OPCODE_operator(opc) == OPR_SUB);
01631 if (issub) {
01632 subop = opc;
01633 addop = OPC_FROM_OPR(OPR_ADD,ty);
01634 } else {
01635 addop = opc;
01636 subop = OPC_FROM_OPR(OPR_SUB,ty);
01637 }
01638 negop = OPC_FROM_OPR(OPR_NEG,ty);
01639
01640
01641 reassoc = FALSE;
01642 if (SIMP_IS_TYPE_INTEGRAL(ty)) {
01643 reassoc = TRUE;
01644 } else if (SIMP_IS_TYPE_FLOATING(ty)) {
01645 reassoc = Enable_Cfold_Reassociate;
01646 }
01647
01648
01649
01650
01651
01652 if (k1const && SIMP_Is_Int_Constant(k1) &&
01653 (SIMP_IS_TYPE_INTEGRAL(ty) && SIMP_Int_ConstVal(k1)==0) ||
01654 (SIMP_IS_TYPE_FLOATING(ty) && is_floating_equal(k1,0.0))) {
01655 SHOW_RULE(" x +- 0 ");
01656 r = k0;
01657 SIMP_DELETE(k1);
01658 return (r);
01659 }
01660 if (k1const && issub && !SIMP_IS_TYPE_UNSIGNED(ty)) {
01661 SHOW_RULE("x - c => x + -c");
01662 r = SIMPNODE_SimpCreateExp2(addop,k0,SIMPNODE_ConstantFold1(negop,k1));
01663 return (r);
01664 }
01665
01666
01667 if (k0const && issub && SIMP_Is_Int_Constant(k0) &&
01668 (SIMP_IS_TYPE_INTEGRAL(ty) && SIMP_Int_ConstVal(k0)==0) ||
01669 (SIMP_IS_TYPE_FLOATING(ty) && is_floating_equal(k0,0.0))) {
01670 SHOW_RULE(" 0 - x ");
01671 r = SIMPNODE_SimpCreateExp1(negop,k1);
01672 SIMP_DELETE(k0);
01673 return (r);
01674 }
01675
01676 if (issub) {
01677 if (SIMPNODE_operator(k1)==OPR_NEG) {
01678 SHOW_RULE(" x - (-y) ");
01679 r = SIMPNODE_SimpCreateExp2(addop,k0,SIMPNODE_kid0(k1));
01680 SIMP_DELETE(k1);
01681 } else if (SIMPNODE_operator(k0)==OPR_NEG) {
01682 if (k1const && !SIMP_IS_TYPE_UNSIGNED(ty)) {
01683 SHOW_RULE("-x - c -> (-c)-x");
01684 r = SIMPNODE_ConstantFold1(negop,k1);
01685 r = SIMPNODE_SimpCreateExp2(subop,r,SIMPNODE_kid0(k0));
01686 SIMP_DELETE(k0);
01687 } else {
01688 SHOW_RULE(" -x - y ");
01689 r = SIMPNODE_SimpCreateExp1(negop,
01690 SIMPNODE_SimpCreateExp2(addop,SIMPNODE_kid0(k0),k1));
01691 SIMP_DELETE(k0);
01692 }
01693 }
01694 } else {
01695 if (SIMPNODE_operator(k0)==OPR_NEG) {
01696 SHOW_RULE(" -x + y ");
01697 r = SIMPNODE_SimpCreateExp2(subop,k1,SIMPNODE_kid0(k0));
01698 SIMP_DELETE(k0);
01699 } else if (SIMPNODE_operator(k1)==OPR_NEG) {
01700 SHOW_RULE(" x + (-y) ");
01701 r = SIMPNODE_SimpCreateExp2(subop,k0,SIMPNODE_kid0(k1));
01702 SIMP_DELETE(k1);
01703 }
01704 }
01705 if (r) return (r);
01706
01707
01708 if (Enable_Cfold_Aggressive && reassoc) {
01709 if (issub && (r=simp_diff_value(k0,k1,FALSE))) {
01710 SHOW_RULE("x-x");
01711 SIMP_DELETE_TREE(k0);
01712 SIMP_DELETE_TREE(k1);
01713 return (r);
01714 }
01715 }
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728 num_const = 0;
01729 num_ops = 0;
01730 if((SIMPNODE_operator(k0)==OPR_ADD || SIMPNODE_operator(k0)==OPR_SUB) &&
01731 (SIMPNODE_operator(k1)==OPR_ADD || SIMPNODE_operator(k1)==OPR_SUB)) {
01732
01733
01734
01735 x[0] = SIMPNODE_kid0(k0);
01736 x[1] = SIMPNODE_kid1(k0);
01737 x[2] = SIMPNODE_kid0(k1);
01738 x[3] = SIMPNODE_kid1(k1);
01739
01740 s[0] = FALSE;
01741 s[1] = (SIMPNODE_operator(k0) == OPR_SUB);
01742 s[2] = FALSE;
01743 s[3] = (SIMPNODE_operator(k1) == OPR_SUB);
01744 if (issub) {
01745 s[2] = !s[2];
01746 s[3] = !s[3];
01747 }
01748 num_ops = 4;
01749
01750 } else if ((SIMPNODE_operator(k0)==OPR_ADD || SIMPNODE_operator(k0)==OPR_SUB) &&
01751 !(SIMPNODE_operator(k1)==OPR_ADD || SIMPNODE_operator(k1)==OPR_SUB)) {
01752 x[0] = SIMPNODE_kid0(k0);
01753 x[1] = SIMPNODE_kid1(k0);
01754 x[2] = k1;
01755
01756 s[0] = FALSE;
01757 s[1] = (SIMPNODE_operator(k0) == OPR_SUB);
01758 s[2] = issub;
01759 num_ops = 3;
01760
01761 } else if (!(SIMPNODE_operator(k0)==OPR_ADD || SIMPNODE_operator(k0)==OPR_SUB) &&
01762 (SIMPNODE_operator(k1)==OPR_ADD || SIMPNODE_operator(k1)==OPR_SUB)) {
01763 x[0] = k0;
01764 x[1] = SIMPNODE_kid0(k1);
01765 x[2] = SIMPNODE_kid1(k1);
01766
01767 s[0] = FALSE;
01768 s[1] = FALSE;
01769 s[2] = (SIMPNODE_operator(k1) == OPR_SUB);
01770 if (issub) {
01771 s[1] = !s[1];
01772 s[2] = !s[2];
01773 }
01774 num_ops = 3;
01775
01776
01777
01778
01779 if (SIMP_Is_Constant(x[0]) && !SIMP_Is_Constant(x[1]) && !SIMP_Is_Constant(x[2]) &&
01780 s[1] && s[2]) {
01781 num_ops = 0;
01782 }
01783 }
01784
01785
01786 if (!reassoc) num_ops = 0;
01787
01788
01789 for (k=0; k < num_ops; k++) {
01790 if (MTYPE_size_reg(SIMPNODE_rtype(x[k])) != MTYPE_size_reg(ty)) {
01791
01792 num_ops = 0;
01793 }
01794 }
01795
01796 if (num_ops != 0) {
01797
01798
01799
01800 constant_moved = FALSE;
01801 for (i=0, j=num_ops-1; i <= j; ) {
01802 if (SIMP_Is_Constant(x[i])) {
01803
01804
01805
01806 if (i != j) {
01807 bt = s[i];
01808 t = x[i];
01809 for (k=i; k<j; k++) {
01810 s[k] = s[k+1];
01811 x[k] = x[k+1];
01812 }
01813 s[j] = bt;
01814 x[j] = t;
01815 constant_moved = TRUE;
01816 }
01817 --j;
01818 ++num_const;
01819 continue;
01820 } else {
01821 ++i;
01822 continue;
01823 }
01824 }
01825
01826
01827
01828 if (num_const == 4) {
01829 SHOW_RULE("Questionable 4 const add fold");
01830
01831
01832
01833 if (s[0]) {
01834 r = SIMPNODE_ConstantFold1(negop,x[0]);
01835 } else {
01836 r = x[0];
01837 }
01838 for (i = 1; i <= 3; i++) {
01839 if (s[i]) {
01840 r = SIMPNODE_ConstantFold2(subop,r,x[i]);
01841 } else {
01842 r = SIMPNODE_ConstantFold2(addop,r,x[i]);
01843 }
01844 }
01845 return (r);
01846 } else if (num_const == 3) {
01847 SHOW_RULE("Questionable 3 const add fold");
01848
01849
01850
01851 ic1 = num_ops-3;
01852 ic2 = num_ops-1;
01853 if (s[ic1]) {
01854 r = SIMPNODE_ConstantFold1(negop,x[ic1]);
01855 } else {
01856 r = x[ic1];
01857 }
01858 for (i = ic1+1; i <= ic2; i++) {
01859 if (s[i]) {
01860 r = SIMPNODE_ConstantFold2(subop,r,x[i]);
01861 } else {
01862 r = SIMPNODE_ConstantFold2(addop,r,x[i]);
01863 }
01864 }
01865 if (ic1 == 0) return (r);
01866 if (s[0]) {
01867 r = SIMPNODE_SimpCreateExp2(subop,r,x[0]);
01868 } else {
01869 r = SIMPNODE_SimpCreateExp2(addop,x[0],r);
01870 }
01871 return (r);
01872 } else if (num_const==2) {
01873
01874 ic1 = num_ops-2;
01875 ic2 = num_ops-1;
01876
01877 if (s[ic1]) x[ic1] = SIMPNODE_ConstantFold1(negop,x[ic1]);
01878
01879 if (s[ic2]) {
01880 x[ic1] = SIMPNODE_ConstantFold2(subop,x[ic1],x[ic2]);
01881 } else {
01882 x[ic1] = SIMPNODE_ConstantFold2(addop,x[ic1],x[ic2]);
01883 }
01884 s[ic1] = FALSE;
01885 --num_ops;
01886 num_const = 1;
01887 }
01888
01889 switch (num_ops) {
01890 case 2:
01891 if (num_const != 1) {
01892
01893 SHOW_RULE("Reassociation goof?");
01894 return(r);
01895 } else {
01896
01897 if (s[0]) {
01898 SHOW_RULE("-x0 + c1 + c2");
01899 r = SIMPNODE_SimpCreateExp2(subop,x[1],x[0]);
01900 } else {
01901 SHOW_RULE("x0 + c1 + c2");
01902 r = SIMPNODE_SimpCreateExp2(addop,x[0],x[1]);
01903 }
01904 return (r);
01905 }
01906 case 3:
01907
01908
01909
01910
01911
01912
01913
01914 if (num_const == 1 && constant_moved) {
01915 if (s[0]) {
01916 if (s[1]) {
01917 SHOW_RULE(" -x0 - x1 + c => c - (x0 + x1) ");
01918 r = SIMPNODE_SimpCreateExp2(addop,x[0],x[1]);
01919 if (s[2]) {
01920 x[2] = SIMPNODE_SimpCreateExp1(negop,x[2]);
01921 }
01922 r = SIMPNODE_SimpCreateExp2(subop,x[2],r);
01923 } else {
01924 SHOW_RULE(" -x0 + x1 + c => (x1 - x0) + c");
01925 r = SIMPNODE_SimpCreateExp2(subop,x[1],x[0]);
01926 r = SIMPNODE_SimpCreateExp2(SELECT_ADD_SUB(s[2]),r,x[2]);
01927 }
01928 } else {
01929 SHOW_RULE(" x0 + s1 x1 + c => (x0 + s1 x1) + c ");
01930 r = SIMPNODE_SimpCreateExp2(SELECT_ADD_SUB(s[1]),x[0],x[1]);
01931 r = SIMPNODE_SimpCreateExp2(SELECT_ADD_SUB(s[2]),r,x[2]);
01932 }
01933 } else if (Enable_Cfold_Aggressive) {
01934
01935 if ((s[0] != s[1]) && (r = simp_diff_value(x[0],x[1],s[0]))) {
01936 SHOW_RULE("x - x op y");
01937 SIMP_DELETE_TREE(x[0]);
01938 SIMP_DELETE_TREE(x[1]);
01939
01940 r = SIMPNODE_SimpCreateExp2(SELECT_ADD_SUB(s[2]),r,x[2]);
01941 } else if ((s[1] != s[2]) && (r = simp_diff_value(x[1],x[2],s[1]))) {
01942
01943 SHOW_RULE("y op x - x");
01944 SIMP_DELETE_TREE(x[1]);
01945 SIMP_DELETE_TREE(x[2]);
01946 r = SIMPNODE_SimpCreateExp2(SELECT_ADD_SUB(s[0]),r,x[0]);
01947 } else if ((s[2] != s[0]) && (r = simp_diff_value(x[2],x[0],s[2]))) {
01948
01949 SHOW_RULE("x op y - x");
01950 SIMP_DELETE_TREE(x[0]);
01951 SIMP_DELETE_TREE(x[2]);
01952 r = SIMPNODE_SimpCreateExp2(SELECT_ADD_SUB(s[1]),r,x[1]);
01953 } else {
01954
01955
01956
01957 r = NULL;
01958 }
01959 }
01960 return (r);
01961
01962 case 4:
01963 if (!Enable_Cfold_Aggressive) return (r);
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974 if (num_const==1) {
01975 i = -1;
01976 if ((s[0] != s[1]) && (dt = simp_diff_value(x[0],x[1],s[0]))) {
01977 SHOW_RULE("4 op, 1 const, cancel 0,1");
01978 i = 2;
01979 d1 = 0; d2 = 1;
01980 } else if ((s[1] != s[2]) && (dt = simp_diff_value(x[1],x[2],s[1]))) {
01981 SHOW_RULE("4 op, 1 const cancel 1,2");
01982 i = 0;
01983 d1 = 1; d2 = 2;
01984 } else if ((s[2] != s[0]) && (dt = simp_diff_value(x[2],x[0],s[2]))) {
01985 SHOW_RULE("4 op, 1 const cancel 0,2");
01986 i = 1;
01987 d1 = 0; d2 = 2;
01988 } else {
01989
01990 r = NULL;
01991 }
01992 if (i != -1) {
01993 if (s[i]) {
01994 if (s[3]) {
01995 r = SIMPNODE_SimpCreateExp2(addop,x[i],x[3]);
01996 r = SIMPNODE_SimpCreateExp1(negop,r);
01997 } else {
01998 r = SIMPNODE_SimpCreateExp2(subop,x[3],x[i]);
01999 }
02000 } else {
02001 r = SIMPNODE_SimpCreateExp2(SELECT_ADD_SUB(s[3]),x[i],x[3]);
02002 }
02003 r = SIMPNODE_SimpCreateExp2(addop,r,dt);
02004 SIMP_DELETE_TREE(x[d1]);
02005 SIMP_DELETE_TREE(x[d2]);
02006 }
02007 } else {
02008 i = -1; j = -1;
02009
02010 if ((s[0] != s[1]) && (dt = simp_diff_value(x[0],x[1],s[0]))) {
02011 SHOW_RULE("4 op, cancel 0,1");
02012 i = 2; j = 3;
02013 d1 = 0; d2 = 1;
02014 } else if ((s[0] != s[2]) && (dt = simp_diff_value(x[0],x[2],s[0]))) {
02015 SHOW_RULE("4 op, cancel 0,2");
02016 i = 1; j = 3;
02017 d1 = 0; d2 = 2;
02018 } else if ((s[0] != s[3]) && (dt = simp_diff_value(x[0],x[3],s[0]))) {
02019 SHOW_RULE("4 op, cancel 0,3");
02020 i = 1; j = 2;
02021 d1 = 0; d2 = 3;
02022 } else if ((s[1] != s[2]) && (dt = simp_diff_value(x[1],x[2],s[1]))) {
02023 SHOW_RULE("4 op, cancel 1,2");
02024 i = 0; j = 3;
02025 d1 = 1; d2 = 2;
02026 } else if ((s[1] != s[3]) && (dt = simp_diff_value(x[1],x[3],s[1]))) {
02027 SHOW_RULE("4 op, cancel 1,3");
02028 i = 0; j = 2;
02029 d1 = 1; d2 = 3;
02030 } else if ((s[2] != s[3]) && (dt = simp_diff_value(x[2],x[3],s[2]))) {
02031 SHOW_RULE("4 op, cancel 2,3");
02032 i = 0; j = 1;
02033 d1 = 2; d2 = 3;
02034 }
02035 if (i == -1) {
02036
02037 r = NULL;
02038 } else {
02039
02040 if (s[i]) {
02041 if (s[j]) {
02042 r = SIMPNODE_SimpCreateExp2(addop,x[i],x[j]);
02043 r = SIMPNODE_SimpCreateExp1(negop,r);
02044 } else {
02045 r = SIMPNODE_SimpCreateExp2(subop,x[j],x[i]);
02046 }
02047 } else {
02048 r = SIMPNODE_SimpCreateExp2(SELECT_ADD_SUB(s[j]),x[i],x[j]);
02049 }
02050 r = SIMPNODE_SimpCreateExp2(addop,r,dt);
02051 SIMP_DELETE_TREE(x[d1]);
02052 SIMP_DELETE_TREE(x[d2]);
02053 }
02054 }
02055 return (r);
02056 }
02057 }
02058
02059 if (r) return (r);
02060
02061
02062
02063
02064 r = simp_factor(k0,k1,OPR_MPY,opc,ty,FACTOR_ALL);
02065 if (!r) r = simp_factor_idty(k0,k1,OPR_MPY,opc,ty,TRUE);
02066 #ifdef WN_SIMP_WORKING_ON_WHIRL
02067
02068 if (r) return (r);
02069
02070
02071 if (k1const &&
02072 SIMP_IS_TYPE_INTEGRAL(ty) &&
02073 SIMPNODE_operator(k0) == OPR_LDA) {
02074 INT64 offset;
02075 INT64 newoffset;
02076 INT64 k1val;
02077 offset = SIMPNODE_lda_offset(k0);
02078 k1val = SIMP_Int_ConstVal(k1);
02079 if (issub) k1val = -k1val;
02080 if (WN_Simp_Fold_LDA &&
02081 is_add_ok(&newoffset,k1val,offset,MTYPE_I4)) {
02082 SHOW_RULE("c1 + LDA");
02083 SIMPNODE_lda_offset(k0) = newoffset;
02084 r = k0;
02085 SIMP_DELETE(k1);
02086 }
02087 }
02088
02089 #endif
02090
02091 return (r);
02092 }
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115 static simpnode simp_times( OPCODE opc,
02116 simpnode k0, simpnode k1, BOOL k0const, BOOL k1const)
02117 {
02118 simpnode r = NULL;
02119 INT64 c1;
02120 TYPE_ID ty;
02121 OPERATOR first_op,second_op;
02122 simpnode addend;
02123
02124
02125
02126
02127 if (k0const) {
02128 return (r);
02129 }
02130 ty = OPCODE_rtype(opc);
02131 first_op = SIMPNODE_operator(k0);
02132 second_op = SIMPNODE_operator(k1);
02133
02134
02135
02136 if (first_op==OPR_NEG && second_op==OPR_NEG) {
02137 SHOW_RULE(" -x*-y ");
02138 r = SIMPNODE_SimpCreateExp2(opc,SIMPNODE_kid0(k0),SIMPNODE_kid0(k1));
02139 SIMP_DELETE(k0);
02140 SIMP_DELETE(k1);
02141 return (r);
02142 } else if (first_op==OPR_NEG && !k1const) {
02143 SHOW_RULE(" -x * y ");
02144 r = SIMPNODE_SimpCreateExp2(opc,SIMPNODE_kid0(k0),k1);
02145 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_NEG,ty),r);
02146 SIMP_DELETE(k0);
02147 return (r);
02148 } else if (second_op==OPR_NEG) {
02149 SHOW_RULE(" x * -y ");
02150 r = SIMPNODE_SimpCreateExp2(opc,k0,SIMPNODE_kid0(k1));
02151 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_NEG,ty),r);
02152 SIMP_DELETE(k1);
02153 return (r);
02154 } else if (first_op==OPR_NEG && k1const) {
02155 SHOW_RULE(" -x * c ");
02156 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_NEG,ty),k1);
02157 r = SIMPNODE_SimpCreateExp2(opc,SIMPNODE_kid0(k0),r);
02158 SIMP_DELETE(k0);
02159 return(r);
02160 }
02161
02162 if (k1const) {
02163 if (SIMP_IS_TYPE_INTEGRAL(ty)) {
02164 c1 = SIMP_Int_ConstVal(k1);
02165 if (c1 == 1) {
02166 SHOW_RULE(" j * 1 ");
02167 r = k0;
02168 SIMP_DELETE(k1);
02169 } else if (c1 == -1 && !SIMP_IS_TYPE_UNSIGNED(ty)) {
02170 SHOW_RULE(" j * -1 ");
02171 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_NEG,ty),k0);
02172 SIMP_DELETE(k1);
02173 } else if (c1 == 0) {
02174 SHOW_RULE(" j * 0 ");
02175 r = SIMP_INTCONST(ty,0);
02176 SIMP_DELETE_TREE(k0);
02177 SIMP_DELETE(k1);
02178 }
02179 } else if (SIMP_IS_TYPE_FLOATING(ty) && !SIMP_IS_TYPE_COMPLEX(ty)) {
02180 if (is_floating_equal(k1,1.0)) {
02181 SHOW_RULE(" a * 1 ");
02182 r = k0;
02183 SIMP_DELETE(k1);
02184 } else if (is_floating_equal(k1,-1.0)) {
02185 SHOW_RULE(" a * -1 ");
02186 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_NEG,ty),k0);
02187 SIMP_DELETE(k1);
02188 } else if (is_floating_equal(k1,0.0)) {
02189 if (IEEE_Arithmetic >= IEEE_INEXACT) {
02190 SHOW_RULE(" j * 0 ");
02191 r = SIMP_FLOATCONST(ty,0.0);
02192 SIMP_DELETE_TREE(k0);
02193 SIMP_DELETE(k1);
02194 }
02195 }
02196 }
02197 if (r) {
02198 return (r);
02199 }
02200
02201 if ((first_op == OPR_ADD || first_op == OPR_SUB) &&
02202 SIMPNODE_rtype(k0) == ty &&
02203 SIMPNODE_rtype(k1) == ty &&
02204 is_ok_to_reassociate(opc)) {
02205 if (SIMP_Is_Constant(SIMPNODE_kid1(k0))) {
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215 SHOW_RULE("(a op c1)*c2");
02216
02217 r = SIMPNODE_CopyNode(k1);
02218 addend = SIMPNODE_SimpCreateExp2(opc,SIMPNODE_kid1(k0),k1);
02219 r = SIMPNODE_SimpCreateExp2(opc,SIMPNODE_kid0(k0),r);
02220 r = SIMPNODE_SimpCreateExp2(SIMPNODE_opcode(k0),r,addend);
02221 SIMP_DELETE(k0);
02222 } else if (SIMP_Is_Constant(SIMPNODE_kid0(k0))) {
02223 SHOW_RULE("(c1 op a )*c2");
02224
02225 r = SIMPNODE_CopyNode(k1);
02226 addend = SIMPNODE_SimpCreateExp2(opc,SIMPNODE_kid0(k0),k1);
02227 r = SIMPNODE_SimpCreateExp2(opc,SIMPNODE_kid1(k0),r);
02228 r = SIMPNODE_SimpCreateExp2(SIMPNODE_opcode(k0),addend,r);
02229 SIMP_DELETE(k0);
02230 }
02231 }
02232 }
02233
02234 if (r) return(r);
02235
02236 if (Enable_Cfold_Aggressive && Roundoff_Level >= ROUNDOFF_SIMPLE) {
02237 if (first_op==OPR_SQRT && second_op==OPR_RECIP
02238 && SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid0(k0),SIMPNODE_kid0(k1))==0) {
02239 SHOW_RULE("sqrt(a)*recip(a)");
02240 r = SIMPNODE_SimpCreateExp2(OPC_FROM_OPR(OPR_DIV,ty),
02241 SIMP_FLOATCONST(ty,1.0) ,k0);
02242 SIMP_DELETE_TREE(k1);
02243 } else if (second_op==OPR_SQRT && first_op==OPR_RECIP
02244 && SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid0(k0),SIMPNODE_kid0(k1))==0) {
02245 SHOW_RULE("recip(a)*sqrt(a)");
02246 r = SIMPNODE_SimpCreateExp2(OPC_FROM_OPR(OPR_DIV,ty),SIMP_FLOATCONST(ty,1.0) ,k1);
02247 SIMP_DELETE_TREE(k0);
02248 } else if (first_op == OPR_RSQRT && SIMPNODE_Simp_Compare_Trees(k1,SIMPNODE_kid0(k0))==0) {
02249 SHOW_RULE("rsqrt(a)*a");
02250 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_SQRT,ty),k1);
02251 SIMP_DELETE_TREE(k0);
02252 } else if (second_op == OPR_RSQRT && SIMPNODE_Simp_Compare_Trees(k0,SIMPNODE_kid0(k1))==0) {
02253 SHOW_RULE("a*rsqrt(a)");
02254 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_SQRT,ty),k0);
02255 SIMP_DELETE_TREE(k1);
02256 }
02257 }
02258
02259 return (r);
02260 }
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283
02284 static simpnode simp_div( OPCODE opc,
02285 simpnode k0, simpnode k1, BOOL k0const, BOOL k1const)
02286 {
02287
02288
02289
02290 simpnode r = NULL;
02291 INT64 c1;
02292 TYPE_ID ty;
02293 TCON recip,dval;
02294
02295 ty = OPCODE_rtype(opc);
02296
02297 if (SIMPNODE_operator(k0)==OPR_NEG && SIMPNODE_operator(k1)==OPR_NEG) {
02298 SHOW_RULE(" -x/-y ");
02299 r = SIMPNODE_SimpCreateExp2(opc,SIMPNODE_kid0(k0),SIMPNODE_kid0(k1));
02300 SIMP_DELETE(k0);
02301 SIMP_DELETE(k1);
02302 return (r);
02303 }
02304
02305 if (k1const && SIMP_IS_TYPE_INTEGRAL(ty)) {
02306 c1 = SIMP_Int_ConstVal(k1);
02307 if (c1 == 1) {
02308 SHOW_RULE(" x / 1 ");
02309 r = k0;
02310 SIMP_DELETE(k1);
02311 } else if (c1==-1 && !SIMP_IS_TYPE_UNSIGNED(ty)) {
02312 SHOW_RULE(" x / (-1) ");
02313 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_NEG,ty),k0);
02314 SIMP_DELETE(k1);
02315 }
02316 }
02317 else if (k1const && SIMP_IS_TYPE_FLOATING(ty)) {
02318
02319
02320
02321
02322
02323 if (is_floating_equal(k1,0.0)) {
02324
02325 return(r);
02326 }
02327 if (is_floating_equal(k1,1.0)) {
02328 SHOW_RULE("x/1");
02329 r = k0;
02330 SIMP_DELETE(k1);
02331 } else if (is_floating_equal(k1,-1.0)) {
02332 SHOW_RULE("x/-1");
02333 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_NEG,ty),k0);
02334 SIMP_DELETE(k1);
02335 } else if (Targ_Is_Power_Of_Two(SIMP_Flt_ConstVal(k1))) {
02336 SHOW_RULE(" a / c a * 1.0/c, if |c| is 2**k ");
02337
02338
02339 dval = SIMP_Flt_ConstVal(k1);
02340 recip = Targ_WhirlOp (opc,
02341 Host_To_Targ_Float (ty, 1.0 ),
02342 dval, 0 );
02343 r = SIMPNODE_CreateFloatconstFromTcon(recip);
02344
02345 r = SIMPNODE_SimpCreateExp2(OPC_FROM_OPR(OPR_MPY,ty),k0,r);
02346 SIMP_DELETE(k1);
02347 }
02348 }
02349
02350 if (r) return (r);
02351 if (k0const && SIMP_IS_TYPE_FLOATING(ty) && !SIMP_IS_TYPE_COMPLEX(ty)) {
02352
02353
02354
02355 if ((is_floating_equal(k0,1.0) ||
02356 is_floating_equal(k0,-1.0)) &&
02357 Recip_Allowed) {
02358 SHOW_RULE("+-1.0 / a");
02359 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_RECIP,ty),k1);
02360 if (is_floating_equal(k0,-1.0)) {
02361 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_NEG,ty),r);
02362 }
02363 SIMP_DELETE(k0);
02364 }
02365 } else if (SIMP_IS_TYPE_FLOATING(ty) && !SIMP_IS_TYPE_COMPLEX(ty)
02366 && Div_Split_Allowed && Recip_Allowed) {
02367 SHOW_RULE(" a / b a * RECIP(b) ");
02368 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_RECIP,ty),k1);
02369 r = SIMPNODE_SimpCreateExp2(OPC_FROM_OPR(OPR_MPY,ty),k0,r);
02370 }
02371
02372 if (!Enable_Cfold_Aggressive || r) return(r);
02373
02374 if (Roundoff_Level >= ROUNDOFF_SIMPLE) {
02375 if (SIMPNODE_operator(k0)==OPR_SQRT
02376 && SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid0(k0),k1)==0) {
02377 SHOW_RULE("sqrt(a)/a");
02378 r = SIMPNODE_SimpCreateExp2(opc, SIMP_FLOATCONST(ty,1.0) ,k0);
02379 SIMP_DELETE_TREE(k1);
02380 } else if (SIMPNODE_operator(k1)==OPR_SQRT
02381 && SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid0(k1),k0)==0) {
02382 SHOW_RULE("a/sqrt(a)");
02383 r = k1;
02384 SIMP_DELETE_TREE(k0);
02385 }
02386 }
02387
02388 if (SIMPNODE_Simp_Compare_Trees(k0,k1) == 0) {
02389 SHOW_RULE("x/x");
02390 if (SIMP_IS_TYPE_INTEGRAL(ty)) {
02391 r = SIMP_INTCONST(ty,1);
02392 } else if (SIMP_IS_TYPE_FLOATING(ty) && !Force_IEEE_Comparisons &&
02393 IEEE_Arithmetic >= IEEE_INEXACT) {
02394 r = SIMP_FLOATCONST(ty,1.0);
02395 }
02396 }
02397
02398 return (r);
02399 }
02400
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423 static simpnode simp_mod_rem(OPCODE opc,
02424 simpnode k0, simpnode k1, BOOL k0const, BOOL k1const)
02425 {
02426 simpnode r = NULL;
02427 INT64 c0,c1;
02428 BOOL isrem,isunsigned;
02429 TYPE_ID ty;
02430
02431 ty = OPCODE_rtype(opc);
02432
02433 if (k0const) {
02434 SHOW_RULE(" 0 rem or mod j ");
02435 c0 = SIMP_Int_ConstVal(k0);
02436 if (c0 == 0) {
02437 r = SIMP_INTCONST(ty,0);
02438 SIMP_DELETE(k0);
02439 SIMP_DELETE_TREE(k1);
02440 }
02441 return(r);
02442 }
02443
02444
02445 if (!(k0const || k1const)) return(r);
02446
02447
02448 c1 = SIMP_Int_ConstVal(k1);
02449 isrem = (OPCODE_operator(opc) == OPR_REM);
02450 isunsigned = SIMP_IS_TYPE_UNSIGNED(ty);
02451
02452 if (c1 == 1 || (c1 == -1 && !isunsigned)) {
02453
02454
02455
02456
02457
02458
02459
02460 SHOW_RULE("j mod/rem +-1");
02461 r = SIMP_INTCONST(ty,0);
02462 SIMP_DELETE_TREE(k0);
02463 SIMP_DELETE(k1);
02464 } else if (!isrem && IS_POWER_OF_2(c1)) {
02465 if (isunsigned || (!isunsigned && (c1 > 0))) {
02466 SHOW_RULE(" j mod (2**N) j & (2**N-1) ");
02467 r = SIMPNODE_SimpCreateExp2(OPC_FROM_OPR(OPR_BAND,ty),k0,
02468 SIMP_INTCONST(ty,c1-1));
02469 SIMP_DELETE(k1);
02470 }
02471 } else if (!isrem && IS_POWER_OF_2(-c1) && !isunsigned) {
02472 SHOW_RULE(" j mod -(2**N) (j & (2**N-1)) - 2**N If j is signed ");
02473
02474 c1 = -c1;
02475 r = SIMPNODE_SimpCreateExp2(OPC_FROM_OPR(OPR_BAND,ty),k0,
02476 SIMP_INTCONST(ty,c1-1));
02477 r = SIMPNODE_SimpCreateExp2(OPC_FROM_OPR(OPR_SUB,ty),r,
02478 SIMP_INTCONST(ty,c1));
02479 SIMP_DELETE(k1);
02480 } else if (isrem && IS_POWER_OF_2(c1) && isunsigned) {
02481 SHOW_RULE(" j rem (2**N) ");
02482 r = SIMPNODE_SimpCreateExp2(OPC_FROM_OPR(OPR_BAND,ty),k0,
02483 SIMP_INTCONST(ty,c1-1));
02484 SIMP_DELETE(k1);
02485 }
02486
02487 return (r);
02488 }
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503
02504 static simpnode simp_power( OPCODE opc,
02505 simpnode k0, simpnode k1, BOOL k0const, BOOL k1const)
02506 {
02507 simpnode r = NULL;
02508 TYPE_ID ty;
02509
02510 if (!(k0const || k1const)) return (r);
02511 ty = OPCODE_rtype(opc);
02512
02513 if (k0const) {
02514 if (is_numeric_equal(k0,1.0)) {
02515 SHOW_RULE(" 1 ** x 1 ");
02516 if (SIMP_IS_TYPE_FLOATING(ty)) {
02517 r = SIMP_FLOATCONST(ty,1.0);
02518 SIMP_DELETE(k0);
02519 SIMP_DELETE_TREE(k1);
02520 } else if (SIMP_IS_TYPE_INTEGRAL(ty)) {
02521 r = SIMP_INTCONST(ty,1);
02522 SIMP_DELETE(k0);
02523 SIMP_DELETE_TREE(k1);
02524 }
02525 } else if (SIMP_IS_TYPE_INTEGRAL(ty) && !SIMP_IS_TYPE_UNSIGNED(ty) &&
02526 SIMP_Int_ConstVal(k0)==-1) {
02527 SHOW_RULE(" -1 ** N 1-(N&1)<<1 ");
02528 r = SIMPNODE_SimpCreateExp2(OPC_FROM_OPR(OPR_BAND,ty),k1,
02529 SIMP_INTCONST(ty,1));
02530 r = SIMPNODE_SimpCreateExp2(OPC_FROM_OPR(OPR_SHL,ty),r,
02531 SIMP_INTCONST(ty,1));
02532 r = SIMPNODE_SimpCreateExp2(OPC_FROM_OPR(OPR_SUB,ty),
02533 SIMP_INTCONST(ty,1),r);
02534 SIMP_DELETE(k0);
02535 }
02536 } else if (k1const) {
02537 if (is_numeric_equal(k1,1.0)) {
02538 SHOW_RULE(" x ** 1 x ");
02539 r = k0;
02540 SIMP_DELETE(k1);
02541 } else if (is_numeric_equal(k1,0.0)) {
02542 SHOW_RULE(" x ** 0 1 ");
02543
02544 if (SIMP_IS_TYPE_FLOATING(ty)) {
02545 r = SIMP_FLOATCONST(ty,1.0);
02546 SIMP_DELETE_TREE(k0);
02547 SIMP_DELETE(k1);
02548 } else if (SIMP_IS_TYPE_INTEGRAL(ty)) {
02549 r = SIMP_INTCONST(ty,1);
02550 SIMP_DELETE_TREE(k0);
02551 SIMP_DELETE(k1);
02552 }
02553 } else if (SIMP_IS_TYPE_FLOATING(ty)) {
02554 if (is_floating_equal(k1,-1.0)) {
02555 SHOW_RULE(" a ** -1 1/a ");
02556 r = SIMPNODE_SimpCreateExp2(OPC_FROM_OPR(OPR_DIV,ty),
02557 SIMP_FLOATCONST(ty,1.0),k0);
02558 SIMP_DELETE(k1);
02559 } else if (is_floating_equal(k1,0.5)) {
02560 SHOW_RULE(" a ** 0.5 SQRT(a) ");
02561 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_SQRT,ty),k0);
02562 SIMP_DELETE(k1);
02563 } else if (is_floating_equal(k1,-0.5)) {
02564 SHOW_RULE(" a ** -0.5 1/SQRT(a) ");
02565 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_SQRT,ty),k0);
02566 r = SIMPNODE_SimpCreateExp2(OPC_FROM_OPR(OPR_DIV,ty),
02567 SIMP_FLOATCONST(ty,1.0),r);
02568 SIMP_DELETE(k1);
02569 }
02570 }
02571
02572 }
02573 return (r);
02574 }
02575
02576
02577
02578
02579
02580
02581
02582
02583
02584
02585
02586
02587
02588
02589
02590
02591
02592
02593 static simpnode simp_min_max(OPCODE opc,
02594 simpnode k0, simpnode k1, BOOL k0const, BOOL k1const)
02595 {
02596 simpnode r = NULL;
02597 BOOL ismax;
02598 INT64 c1;
02599
02600 ismax = (OPCODE_operator(opc) == OPR_MAX);
02601 if (k1const && SIMP_Is_Int_Constant(k1)) {
02602 c1 = SIMP_Int_ConstVal(k1);
02603 switch (OPCODE_rtype(opc)) {
02604 case MTYPE_I4:
02605 if ((ismax && c1==INT32_MIN) ||
02606 (!ismax && c1==INT32_MAX)) {
02607 r = k0;
02608 SIMP_DELETE(k1);
02609 } else if ((ismax && c1==INT32_MAX) ||
02610 (!ismax && c1==INT32_MIN)){
02611 r = k1;
02612 SIMP_DELETE_TREE(k0);
02613 }
02614 break;
02615
02616 case MTYPE_U4:
02617 if ((ismax && c1==0) ||
02618 (!ismax && c1==UINT32_MAX)) {
02619 r = k0;
02620 SIMP_DELETE(k1);
02621 } else if ((ismax && c1==UINT32_MAX) ||
02622 (!ismax && c1==0)){
02623 r = k1;
02624 SIMP_DELETE_TREE(k0);
02625 }
02626 break;
02627
02628 case MTYPE_I8:
02629 if ((ismax && c1==0x8000000000000000LL) ||
02630 (!ismax && c1==0x7fffffffffffffffLL)) {
02631 r = k0;
02632 SIMP_DELETE(k1);
02633 } else if ((ismax && c1==0x7fffffffffffffffLL) ||
02634 (!ismax && c1==0x8000000000000000LL)){
02635 r = k1;
02636 SIMP_DELETE_TREE(k0);
02637 }
02638 break;
02639
02640 case MTYPE_U8:
02641 if ((ismax && c1==0) ||
02642 (!ismax && c1==(UINT64) -1)) {
02643 r = k0;
02644 SIMP_DELETE(k1);
02645 } else if ((ismax && c1==(UINT64) -1) ||
02646 (!ismax && c1==0)){
02647 r = k1;
02648 SIMP_DELETE_TREE(k0);
02649 }
02650 break;
02651 }
02652 }
02653
02654 if (r) {
02655 SHOW_RULE("MIN/MAX(x, largest/smallest)");
02656 return (r);
02657 }
02658
02659 if (!Enable_Cfold_Aggressive) return (r);
02660 if (SIMPNODE_Simp_Compare_Trees(k0,k1)==0) {
02661 SHOW_RULE(" MAX(x,x), MIN(x,x) ");
02662 r = k0;
02663 SIMP_DELETE_TREE(k1);
02664 }
02665 return (r);
02666 }
02667
02668
02669
02670
02671
02672
02673
02674
02675
02676
02677
02678
02679
02680
02681
02682
02683
02684
02685
02686 static simpnode simp_band( OPCODE opc,
02687 simpnode k0, simpnode k1, BOOL k0const, BOOL k1const)
02688 {
02689
02690 simpnode r = NULL;
02691 INT64 c1,mask_bits;
02692 TYPE_ID ty;
02693
02694
02695
02696 if (k0const) {
02697 return (r);
02698 }
02699 ty = OPCODE_rtype(opc);
02700
02701 if (k1const) {
02702 c1 = SIMP_Int_ConstVal(k1);
02703 if (c1 == 0) {
02704 SHOW_RULE("j&0");
02705 r = SIMP_INTCONST(ty,0);
02706 SIMP_DELETE_TREE(k0);
02707 SIMP_DELETE(k1);
02708 } else if (c1 == -1) {
02709 SHOW_RULE("j&-1");
02710 r = k0;
02711 SIMP_DELETE(k1);
02712 } else if ((c1 == 1) && (get_inverse_relop(SIMPNODE_opcode(k0))!=0)) {
02713 SHOW_RULE("<comp> & 1");
02714 r = k0;
02715 SIMP_DELETE(k1);
02716 } else if ((SIMPNODE_operator(k0) == OPR_BIOR) && SIMP_Is_Constant(SIMPNODE_kid1(k0)) &&
02717 ((SIMP_Int_ConstVal(SIMPNODE_kid1(k0)) & c1) == 0)) {
02718 SHOW_RULE("(j|c1) & c2, c1&c2=0");
02719 r = SIMPNODE_SimpCreateExp2(opc,SIMPNODE_kid0(k0),k1);
02720 SIMP_DELETE(SIMPNODE_kid1(k0));
02721 SIMP_DELETE(k0);
02722 } else if ((SIMPNODE_operator(k0) == OPR_LSHR) &&
02723 SIMP_Is_Constant(SIMPNODE_kid1(k0)) &&
02724 (MTYPE_bit_size(SIMPNODE_rtype(k0)) == MTYPE_bit_size(ty))) {
02725 INT32 shift_count = SIMP_Int_ConstVal(SIMPNODE_kid1(k0));
02726 mask_bits = create_bitmask(MTYPE_bit_size(ty) - shift_count);
02727 if ((mask_bits & c1) == mask_bits) {
02728 SHOW_RULE("(j LSHR c2) & c1)");
02729 r = k0;
02730 SIMP_DELETE(k1);
02731 } else if (Enable_extract_compose && IS_POWER_OF_2(c1+1)) {
02732 r = SIMPNODE_SimpCreateExtract(MTYPE_bit_size(ty) == 32 ? OPC_U4EXTRACT_BITS : OPC_U8EXTRACT_BITS,
02733 shift_count,wn_simp_code::log2(c1+1),
02734 SIMPNODE_kid0(k0));
02735 SIMP_DELETE(k1);
02736 SIMP_DELETE(SIMPNODE_kid1(k0));
02737 }
02738 }
02739 } else if ((SIMPNODE_operator(k0)==OPR_BNOT) && (SIMPNODE_operator(k1)==OPR_BNOT)) {
02740 SHOW_RULE(" ~j & ~k ");
02741 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_BNOT,ty),
02742 SIMPNODE_SimpCreateExp2(OPC_FROM_OPR(OPR_BIOR,ty),
02743 SIMPNODE_kid0(k0),SIMPNODE_kid0(k1)));
02744 SIMP_DELETE(k0);
02745 SIMP_DELETE(k1);
02746 } else if ((SIMPNODE_operator(k0)==OPR_EQ) && (SIMPNODE_operator(k1)==OPR_EQ) &&
02747 SIMP_Is_Int_Constant(SIMPNODE_kid1(k0)) &&
02748 SIMP_Is_Int_Constant(SIMPNODE_kid1(k1)) &&
02749 SIMP_Int_ConstVal(SIMPNODE_kid1(k0)) == 0 &&
02750 SIMP_Int_ConstVal(SIMPNODE_kid1(k1)) == 0 &&
02751 (SIMP_TYPE(SIMPNODE_kid0(k0)) == SIMP_TYPE(SIMPNODE_kid0(k1))) &&
02752 (ty == SIMP_TYPE(SIMPNODE_kid0(k0)))) {
02753 SHOW_RULE(" (j==0) & (k==0) ");
02754
02755 r = SIMPNODE_SimpCreateExp2(SIMPNODE_opcode(k0),
02756 SIMPNODE_SimpCreateExp2(OPC_FROM_OPR(OPR_BIOR,ty),
02757 SIMPNODE_kid0(k0), SIMPNODE_kid0(k1)),
02758 SIMPNODE_kid1(k0));
02759 SIMP_DELETE(k0);
02760 SIMP_DELETE(SIMPNODE_kid1(k1));
02761 SIMP_DELETE(k1);
02762 }
02763
02764 if (!Enable_Cfold_Aggressive || r) return (r);
02765
02766 if ((SIMPNODE_operator(k0)==OPR_BNOT && SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid0(k0),k1)==0) ||
02767 (SIMPNODE_operator(k1)==OPR_BNOT && SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid0(k1),k0)==0)) {
02768 SHOW_RULE(" ~j & j ");
02769 r = SIMP_INTCONST(ty,0);
02770 SIMP_DELETE_TREE(k0);
02771 SIMP_DELETE_TREE(k1);
02772 } else if (SIMPNODE_Simp_Compare_Trees(k0,k1)==0) {
02773 SHOW_RULE(" j & j ");
02774 r = k0;
02775 SIMP_DELETE_TREE(k1);
02776 }
02777
02778 if (r) return (r);
02779
02780 r = simp_factor(k0,k1,OPR_BIOR,opc,ty,FACTOR_ALL);
02781 if (r) return (r);
02782
02783 r = simp_factor_idty(k0,k1,OPR_BIOR,opc,ty,FALSE);
02784 if (r) return (r);
02785
02786
02787 r = simp_factor(k0,k1,OPR_BAND,opc,ty,FACTOR_ALL);
02788 if (r) return (r);
02789
02790 r = simp_factor_idty(k0,k1,OPR_BAND,opc,ty,FALSE);
02791 if (r) return (r);
02792
02793 r = simp_factor(k0,k1,OPR_SHL,opc,ty,FACTOR_22);
02794 if (r) return (r);
02795
02796 r = simp_factor(k0,k1,OPR_ASHR,opc,ty,FACTOR_22);
02797 if (r) return (r);
02798
02799 r = simp_factor(k0,k1,OPR_LSHR,opc,ty,FACTOR_22);
02800
02801 return (r);
02802 }
02803
02804
02805
02806
02807
02808
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823 static simpnode simp_bior( OPCODE opc,
02824 simpnode k0, simpnode k1, BOOL k0const, BOOL k1const)
02825 {
02826 simpnode r = NULL;
02827 INT64 c1,c2;
02828 TYPE_ID ty;
02829
02830
02831
02832 if (k0const) {
02833 return (r);
02834 }
02835 ty = OPCODE_rtype(opc);
02836
02837 if (k1const) {
02838 c1 = SIMP_Int_ConstVal(k1);
02839 if (c1 == 0) {
02840 SHOW_RULE("j|0");
02841 r = k0;
02842 SIMP_DELETE(k1);
02843 } else if (c1 == -1) {
02844 SHOW_RULE("j|-1");
02845 r = SIMP_INTCONST(ty,-1);
02846 SIMP_DELETE_TREE(k0);
02847 SIMP_DELETE(k1);
02848 } else if ((c1 == 1) && (get_inverse_relop(SIMPNODE_opcode(k0))!=0)) {
02849 SHOW_RULE("<comp> | 1");
02850 r = SIMP_INTCONST(ty,1);
02851 SIMP_DELETE_TREE(k0);
02852 SIMP_DELETE(k1);
02853 } else if ((SIMPNODE_operator(k0) == OPR_BAND) &&
02854 (SIMP_Is_Constant(SIMPNODE_kid1(k0)))) {
02855 c2 = SIMP_Int_ConstVal(SIMPNODE_kid1(k0));
02856 if ((c2 | c1) == -1) {
02857 SHOW_RULE("(j & c2) | c1");
02858 r = SIMPNODE_SimpCreateExp2(opc,SIMPNODE_kid0(k0),k1);
02859 SIMP_DELETE(k0);
02860 SIMP_DELETE(SIMPNODE_kid1(k0));
02861 }
02862 }
02863
02864 } else if ((SIMPNODE_operator(k0)==OPR_BNOT) && (SIMPNODE_operator(k1)==OPR_BNOT)) {
02865 SHOW_RULE(" ~j | ~k ");
02866 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_BNOT,ty),
02867 SIMPNODE_SimpCreateExp2(OPC_FROM_OPR(OPR_BAND,ty),
02868 SIMPNODE_kid0(k0),SIMPNODE_kid0(k1)));
02869 SIMP_DELETE(k0);
02870 SIMP_DELETE(k1);
02871
02872 } else if ((SIMPNODE_operator(k0)==OPR_NE) && (SIMPNODE_operator(k1)==OPR_NE) &&
02873 SIMP_Is_Int_Constant(SIMPNODE_kid1(k0)) &&
02874 SIMP_Is_Int_Constant(SIMPNODE_kid1(k1)) &&
02875 SIMP_Int_ConstVal(SIMPNODE_kid1(k0)) == 0 &&
02876 SIMP_Int_ConstVal(SIMPNODE_kid1(k1)) == 0 &&
02877 (SIMP_TYPE(SIMPNODE_kid0(k0)) == SIMP_TYPE(SIMPNODE_kid0(k1))) &&
02878 (OPCODE_rtype(opc) == (SIMP_TYPE(SIMPNODE_kid0(k0))))) {
02879 SHOW_RULE(" (j!=0) | (k!=0) ");
02880
02881 r = SIMPNODE_SimpCreateExp2(SIMPNODE_opcode(k0),
02882 SIMPNODE_SimpCreateExp2(opc, SIMPNODE_kid0(k0), SIMPNODE_kid0(k1)),
02883 SIMPNODE_kid1(k0));
02884 SIMP_DELETE(k0);
02885 SIMP_DELETE(SIMPNODE_kid1(k1));
02886 SIMP_DELETE(k1);
02887 }
02888
02889 if (!Enable_Cfold_Aggressive || r) return (r);
02890
02891 if ((SIMPNODE_operator(k0)==OPR_BNOT && SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid0(k0),k1)==0) ||
02892 (SIMPNODE_operator(k1)==OPR_BNOT && SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid0(k1),k0)==0)) {
02893 SHOW_RULE(" ~j | j ");
02894 r = SIMP_INTCONST(ty,-1);
02895 SIMP_DELETE_TREE(k0);
02896 SIMP_DELETE_TREE(k1);
02897 } else if (SIMPNODE_Simp_Compare_Trees(k0,k1)==0) {
02898 SHOW_RULE(" j | j ");
02899 r = k0;
02900 SIMP_DELETE_TREE(k1);
02901 }
02902
02903 if (r) return (r);
02904
02905 if (SIMPNODE_operator(k0) == OPR_BAND && SIMPNODE_operator(k1) == OPR_COMPOSE_BITS &&
02906 SIMP_Is_Constant(SIMPNODE_kid1(k0)) && SIMP_Is_Constant(SIMPNODE_kid0(k1)) &&
02907 SIMP_Int_ConstVal(SIMPNODE_kid0(k1)) == 0)
02908 {
02909
02910 UINT64 dep_mask = create_bitmask(SIMPNODE_op_bit_size(k1))<<SIMPNODE_op_bit_offset(k1);
02911 UINT64 type_mask = create_bitmask(MTYPE_bit_size(ty));
02912 c1 = SIMP_Int_ConstVal(SIMPNODE_kid1(k0));
02913 if (((dep_mask & c1) == 0) && (((dep_mask | c1) & type_mask) == type_mask)) {
02914 SHOW_RULE("(j&mask)|compose(0,k)");
02915 r = SIMPNODE_SimpCreateDeposit(SIMPNODE_opcode(k1),SIMPNODE_op_bit_offset(k1),
02916 SIMPNODE_op_bit_size(k1),SIMPNODE_kid0(k0),SIMPNODE_kid1(k1));
02917 SIMP_DELETE(SIMPNODE_kid1(k0));
02918 SIMP_DELETE(SIMPNODE_kid0(k1));
02919 SIMP_DELETE(k0);
02920 SIMP_DELETE(k1);
02921 }
02922 }
02923 if (Enable_extract_compose && SIMPNODE_operator(k0) == OPR_BAND && SIMPNODE_operator(k1) == OPR_BAND
02924 && SIMP_Is_Constant(SIMPNODE_kid1(k0)) && SIMP_Is_Constant(SIMPNODE_kid1(k1)))
02925 {
02926 c1 = SIMP_Int_ConstVal(SIMPNODE_kid1(k0));
02927 c2 = SIMP_Int_ConstVal(SIMPNODE_kid1(k1));
02928 UINT64 type_mask = create_bitmask(MTYPE_bit_size(ty));
02929
02930 if (IS_POWER_OF_2(c1+1) && ((c2 & c1) == 0) && (((c2 | c1) & type_mask) == type_mask)) {
02931 SHOW_RULE("(J&mask1) | (k & mask2)");
02932 r = SIMPNODE_SimpCreateDeposit(OPC_FROM_OPR(OPR_COMPOSE_BITS,ty),0,wn_simp_code::log2(c1+1),
02933 SIMPNODE_kid0(k1),SIMPNODE_kid0(k0));
02934 SIMP_DELETE(SIMPNODE_kid1(k0));
02935 SIMP_DELETE(SIMPNODE_kid1(k1));
02936 SIMP_DELETE(k0);
02937 SIMP_DELETE(k1);
02938 } else if (IS_POWER_OF_2(c2+1) && ((c2 & c1) == 0) && (((c2 | c1) & type_mask) == type_mask)) {
02939 SHOW_RULE("(J&mask2) | (k & mask1)");
02940 r = SIMPNODE_SimpCreateDeposit(OPC_FROM_OPR(OPR_COMPOSE_BITS,ty),0,wn_simp_code::log2(c2+1),
02941 SIMPNODE_kid0(k0),SIMPNODE_kid0(k1));
02942 SIMP_DELETE(SIMPNODE_kid1(k0));
02943 SIMP_DELETE(SIMPNODE_kid1(k1));
02944 SIMP_DELETE(k0);
02945 SIMP_DELETE(k1);
02946 }
02947 }
02948 if (r) return (r);
02949
02950 r = simp_factor(k0,k1,OPR_BAND,opc,ty,FACTOR_ALL);
02951 if (r) return (r);
02952
02953 r = simp_factor_idty(k0,k1,OPR_BAND,opc,ty,FALSE);
02954 if (r) return (r);
02955
02956
02957 r = simp_factor(k0,k1,OPR_BIOR,opc,ty,FACTOR_ALL);
02958 if (r) return (r);
02959
02960 r = simp_factor_idty(k0,k1,OPR_BIOR,opc,ty,FALSE);
02961 if (r) return (r);
02962
02963 r = simp_factor(k0,k1,OPR_SHL,opc,ty,FACTOR_22);
02964 if (r) return (r);
02965
02966 r = simp_factor(k0,k1,OPR_ASHR,opc,ty,FACTOR_22);
02967 if (r) return (r);
02968
02969 r = simp_factor(k0,k1,OPR_LSHR,opc,ty,FACTOR_22);
02970
02971 return (r);
02972 }
02973
02974
02975
02976
02977
02978
02979
02980 static simpnode simp_bnor( OPCODE opc,
02981 simpnode k0, simpnode k1, BOOL k0const, BOOL k1const)
02982 {
02983 simpnode r = NULL;
02984 TYPE_ID ty;
02985
02986 ty = OPCODE_rtype(opc);
02987 r = SIMPNODE_SimplifyExp2(OPC_FROM_OPR(OPR_BIOR,ty),k0,k1);
02988 if (r) {
02989
02990 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_BNOT,ty),r);
02991 }
02992 if (r) {
02993 SHOW_RULE("BNOR simplified");
02994 }
02995 return (r);
02996 }
02997
02998
02999
03000
03001
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012 static simpnode simp_bxor( OPCODE opc,
03013 simpnode k0, simpnode k1, BOOL k0const, BOOL k1const)
03014 {
03015 simpnode r = NULL;
03016 INT64 c1;
03017 OPCODE inv_opc;
03018 TYPE_ID ty;
03019
03020
03021
03022 if (k0const) {
03023 return (r);
03024 }
03025
03026 ty = OPCODE_rtype(opc);
03027
03028 if (k1const) {
03029 c1 = SIMP_Int_ConstVal(k1);
03030 if (c1 == 0) {
03031 SHOW_RULE("j^0");
03032 r = k0;
03033 SIMP_DELETE(k1);
03034 } else if (c1 == -1) {
03035 SHOW_RULE("j^-1");
03036 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_BNOT,OPCODE_rtype(opc)),
03037 k0);
03038 SIMP_DELETE(k1);
03039 } else if ((c1 == 1) && ((inv_opc=get_inverse_relop(SIMPNODE_opcode(k0)))!=0)) {
03040 if (! (Force_IEEE_Comparisons &&
03041 SIMP_IS_TYPE_FLOATING(OPCODE_desc(inv_opc)))) {
03042 SHOW_RULE("<comp> ^ 1 ");
03043 r = SIMPNODE_SimpCreateExp2(inv_opc,SIMPNODE_kid0(k0),SIMPNODE_kid1(k0));
03044 SIMP_DELETE(k0);
03045 SIMP_DELETE(k1);
03046 }
03047 }
03048 }
03049
03050 if (!Enable_Cfold_Aggressive || r) return (r);
03051
03052 if ((SIMPNODE_operator(k0)==OPR_BNOT && SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid0(k0),k1)==0) ||
03053 (SIMPNODE_operator(k1)==OPR_BNOT && SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid0(k1),k0)==0)) {
03054 SHOW_RULE(" ~j ^ j ");
03055 r = SIMP_INTCONST(ty,-1);
03056 SIMP_DELETE_TREE(k0);
03057 SIMP_DELETE_TREE(k1);
03058 } else if (SIMPNODE_Simp_Compare_Trees(k0,k1)==0) {
03059 SHOW_RULE(" j ^ j ");
03060 r = SIMP_INTCONST(ty,0);
03061 SIMP_DELETE_TREE(k0);
03062 SIMP_DELETE_TREE(k1);
03063 }
03064
03065 if (r) return (r);
03066
03067 r = simp_factor(k0,k1,OPR_BAND,opc,ty,FACTOR_ALL);
03068 if (r) return (r);
03069
03070 r = simp_factor_idty(k0,k1,OPR_BAND,opc,ty,FALSE);
03071 if (r) return (r);
03072
03073 r = simp_factor(k0,k1,OPR_SHL,opc,ty,FACTOR_22);
03074 if (r) return (r);
03075
03076 r = simp_factor(k0,k1,OPR_ASHR,opc,ty,FACTOR_22);
03077 if (r) return (r);
03078
03079 r = simp_factor(k0,k1,OPR_LSHR,opc,ty,FACTOR_22);
03080
03081 return (r);
03082 }
03083
03084
03085
03086
03087
03088
03089
03090
03091
03092
03093
03094
03095
03096
03097
03098
03099 static simpnode simp_land( OPCODE opc,
03100 simpnode k0, simpnode k1, BOOL k0const, BOOL k1const)
03101 {
03102 simpnode r = NULL;
03103 INT64 c1;
03104 TYPE_ID ty;
03105
03106
03107
03108 if (k0const) {
03109 return (r);
03110 }
03111 ty = OPCODE_rtype(opc);
03112
03113 if (k1const) {
03114 c1 = SIMP_Int_ConstVal(k1);
03115 if (c1 == 0) {
03116 SHOW_RULE(" j&&0");
03117 r = SIMP_INTCONST(ty,0);
03118 SIMP_DELETE_TREE(k0);
03119 SIMP_DELETE(k1);
03120 } else {
03121 SHOW_RULE(" j&&1");
03122 r = k0;
03123 SIMP_DELETE(k1);
03124 }
03125
03126 } else if ((SIMPNODE_operator(k0)==OPR_LNOT) && (SIMPNODE_operator(k1)==OPR_LNOT)) {
03127 SHOW_RULE(" !j && !k ");
03128 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_LNOT,ty),
03129 SIMPNODE_SimpCreateExp2(OPC_FROM_OPR(OPR_LIOR,ty),
03130 SIMPNODE_kid0(k0),SIMPNODE_kid0(k1)));
03131 SIMP_DELETE(k0);
03132 SIMP_DELETE(k1);
03133 }
03134
03135 if (!Enable_Cfold_Aggressive || r) return (r);
03136
03137 if ((SIMPNODE_operator(k0)==OPR_LNOT && SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid0(k0),k1)==0) ||
03138 (SIMPNODE_operator(k1)==OPR_LNOT && SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid0(k1),k0)==0)) {
03139 SHOW_RULE(" !j && j ");
03140 r = SIMP_INTCONST(ty,0);
03141 SIMP_DELETE_TREE(k0);
03142 SIMP_DELETE_TREE(k1);
03143 } else if (SIMPNODE_Simp_Compare_Trees(k0,k1)==0) {
03144 SHOW_RULE(" j && j ");
03145 r = k0;
03146 SIMP_DELETE_TREE(k1);
03147 }
03148
03149 if (r) return (r);
03150
03151 r = simp_factor(k0,k1,OPR_LIOR,opc,ty,FACTOR_ALL);
03152 if (!r) r = simp_factor_idty(k0,k1,OPR_LIOR,opc,ty,FALSE);
03153
03154 return (r);
03155 }
03156
03157
03158
03159
03160
03161
03162
03163
03164
03165
03166
03167
03168
03169
03170
03171 static simpnode simp_lior( OPCODE opc,
03172 simpnode k0, simpnode k1, BOOL k0const, BOOL k1const)
03173 {
03174 simpnode r = NULL;
03175 INT64 c1;
03176 TYPE_ID ty;
03177
03178
03179
03180 if (k0const) {
03181 return (r);
03182 }
03183 ty = OPCODE_rtype(opc);
03184
03185 if (k1const) {
03186 c1 = SIMP_Int_ConstVal(k1);
03187 if (c1 == 0) {
03188 SHOW_RULE("j||0");
03189 r = k0;
03190 SIMP_DELETE(k1);
03191 } else {
03192 SHOW_RULE("j||1");
03193 r = SIMP_INTCONST(ty,1);
03194 SIMP_DELETE_TREE(k0);
03195 SIMP_DELETE(k1);
03196 }
03197 } else if ((SIMPNODE_operator(k0)==OPR_LNOT) && (SIMPNODE_operator(k1)==OPR_LNOT)) {
03198 SHOW_RULE(" !j || !k ");
03199 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_LNOT,ty),
03200 SIMPNODE_SimpCreateExp2(OPC_FROM_OPR(OPR_LAND,ty),
03201 SIMPNODE_kid0(k0),SIMPNODE_kid0(k1)));
03202 SIMP_DELETE(k0);
03203 SIMP_DELETE(k1);
03204 }
03205
03206 if (!Enable_Cfold_Aggressive || r) return (r);
03207
03208 if ((SIMPNODE_operator(k0)==OPR_LNOT && SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid0(k0),k1)==0) ||
03209 (SIMPNODE_operator(k1)==OPR_LNOT && SIMPNODE_Simp_Compare_Trees(SIMPNODE_kid0(k1),k0)==0)) {
03210 SHOW_RULE(" !j || j ");
03211 r = SIMP_INTCONST(ty,1);
03212 SIMP_DELETE_TREE(k0);
03213 SIMP_DELETE_TREE(k1);
03214 } else if (SIMPNODE_Simp_Compare_Trees(k0,k1)==0) {
03215 SHOW_RULE(" j || j ");
03216 r = k0;
03217 SIMP_DELETE_TREE(k1);
03218 }
03219
03220 if (r) return (r);
03221
03222 r = simp_factor(k0,k1,OPR_LAND,opc,ty,FACTOR_ALL);
03223 if (!r) r = simp_factor_idty(k0,k1,OPR_LAND,opc,ty,TRUE);
03224
03225 return (r);
03226 }
03227
03228
03229
03230
03231
03232
03233
03234
03235
03236
03237 static simpnode simp_cand( OPCODE opc,
03238 simpnode k0, simpnode k1, BOOL k0const, BOOL k1const)
03239 {
03240 simpnode r = NULL;
03241 INT64 c1;
03242
03243 if (k0const) {
03244 c1 = SIMP_Int_ConstVal(k0);
03245 if (c1 == 0) {
03246 SHOW_RULE(" 0 c&& j");
03247 r = SIMP_INTCONST(OPCODE_rtype(opc),0);
03248 SIMP_DELETE(k0);
03249 SIMP_DELETE_TREE(k1);
03250 } else {
03251 SHOW_RULE(" 1 c&& j");
03252 r = k1;
03253 SIMP_DELETE(k0);
03254 }
03255 } else if (k1const) {
03256 c1 = SIMP_Int_ConstVal(k1);
03257 if (c1 != 0) {
03258 SHOW_RULE(" j c&& 1");
03259 r = k0;
03260 SIMP_DELETE(k1);
03261 }
03262 }
03263
03264 return (r);
03265 }
03266
03267
03268
03269
03270
03271
03272
03273
03274
03275
03276
03277 static simpnode simp_cior( OPCODE opc,
03278 simpnode k0, simpnode k1, BOOL k0const, BOOL k1const)
03279 {
03280 simpnode r = NULL;
03281 INT64 c1;
03282
03283
03284
03285 if (k0const) {
03286 return (r);
03287 }
03288
03289 if (k0const) {
03290 c1 = SIMP_Int_ConstVal(k0);
03291 if (c1 == 0) {
03292 SHOW_RULE("0 c|| j");
03293 r = k1;
03294 SIMP_DELETE(k0);
03295 } else {
03296 SHOW_RULE("1 c|| j");
03297 r = SIMP_INTCONST(OPCODE_rtype(opc),1);
03298 SIMP_DELETE(k0);
03299 SIMP_DELETE_TREE(k1);
03300 }
03301 } else if (k1const) {
03302 c1 = SIMP_Int_ConstVal(k1);
03303 if (c1 == 0) {
03304 SHOW_RULE("j c|| 0");
03305 r = k0;
03306 SIMP_DELETE(k1);
03307 }
03308 }
03309
03310 return (r);
03311 }
03312
03313
03314
03315
03316
03317
03318
03319
03320
03321
03322
03323
03324
03325
03326
03327
03328
03329
03330
03331
03332
03333
03334
03335
03336
03337
03338
03339
03340
03341 static simpnode simp_shift( OPCODE opc,
03342 simpnode k0, simpnode k1, BOOL k0const, BOOL k1const)
03343 {
03344 simpnode r = NULL;
03345 INT64 c1,c2,mask;
03346 TYPE_ID ty,rty;
03347 INT64 shift_size;
03348 BOOL firstop_is_shift=FALSE;
03349 INT64 shift_size2;
03350 OPERATOR firstop, op;
03351 OPCODE first_opcode;
03352 simpnode tmp;
03353
03354 op = OPCODE_operator(opc);
03355 ty = OPCODE_rtype(opc);
03356 if (ty==MTYPE_U8 || ty==MTYPE_I8) {
03357 shift_size = 64;
03358 } else {
03359 shift_size = 32;
03360 }
03361 first_opcode = SIMPNODE_opcode(k0);
03362 firstop = OPCODE_operator(first_opcode);
03363 if (firstop == OPR_SHL || firstop == OPR_ASHR ||
03364 firstop == OPR_LSHR) {
03365 firstop_is_shift=TRUE;
03366 if (SIMPNODE_rtype(k0) == MTYPE_U8 ||
03367 SIMPNODE_rtype(k0) == MTYPE_I8) {
03368 shift_size2 = 64;
03369 } else {
03370 shift_size2 = 32;
03371 }
03372 }
03373
03374 if (k1const) {
03375 if (ARCH_mask_shift_counts) {
03376 c1 = SIMP_Int_ConstVal(k1) & (shift_size-1);
03377 } else {
03378 c1 = MIN((UINT64) SIMP_Int_ConstVal(k1),shift_size);
03379 }
03380
03381
03382
03383
03384
03385 if (c1 == 0) {
03386 SHOW_RULE("j shift 0");
03387 r = k0;
03388 SIMP_DELETE(k1);
03389 return (r);
03390 }
03391
03392
03393
03394 if (c1 >= shift_size) {
03395 if (op != OPR_ASHR) {
03396
03397 SHOW_RULE("j shift big count -> 0");
03398 r = SIMP_INTCONST(OPCODE_rtype(opc),0);
03399 SIMP_DELETE_TREE(k0);
03400 SIMP_DELETE(k1);
03401 } else {
03402 SHOW_RULE("j ASHR bigcount");
03403 r = SIMPNODE_SimpCreateExp2(opc,k0,SIMP_INTCONST(ty, shift_size-1));
03404 SIMP_DELETE(k1);
03405 }
03406 return (r);
03407 }
03408 if (!WHIRL_Keep_Cvt_On &&
03409 op == OPR_SHL &&
03410 firstop == OPR_CVT &&
03411 SIMP_IS_TYPE_INTEGRAL(OPCODE_rtype(first_opcode)) &&
03412 SIMP_IS_TYPE_INTEGRAL(OPCODE_desc(first_opcode)) &&
03413 c1 >= 32) {
03414 SHOW_RULE("Integer CVT << c1, c1>=32");
03415 r = SIMPNODE_SimpCreateExp2(opc,SIMPNODE_kid0(k0),k1);
03416 SIMP_DELETE(k0);
03417 } else if (firstop_is_shift && shift_size==shift_size2 &&
03418 SIMP_Is_Constant(SIMPNODE_kid1(k0))) {
03419 if (ARCH_mask_shift_counts) {
03420 c2 = SIMP_Int_ConstVal(SIMPNODE_kid1(k0)) & (shift_size-1);
03421 } else {
03422 c2 = MIN((UINT64) SIMP_Int_ConstVal(SIMPNODE_kid1(k0)),shift_size);
03423 }
03424 if (firstop == op ) {
03425
03426
03427
03428
03429 if ((c1 + c2) >= shift_size) {
03430 if (op != OPR_ASHR) {
03431
03432 SHOW_RULE("j shift c2 shift c1 -> 0");
03433 r = SIMP_INTCONST(OPCODE_rtype(opc), 0);
03434 SIMP_DELETE_TREE(k0);
03435 SIMP_DELETE_TREE(k1);
03436 } else {
03437 SHOW_RULE("j ASHR c2 ASHR c1");
03438 r = SIMPNODE_SimpCreateExp2(opc,SIMPNODE_kid0(k0),SIMP_INTCONST(ty, shift_size-1));
03439 SIMP_DELETE(SIMPNODE_kid1(k0));
03440 SIMP_DELETE(k0);
03441 SIMP_DELETE(k1);
03442 }
03443 } else {
03444
03445 SHOW_RULE("j shift c2 shift c1");
03446 r = SIMPNODE_SimpCreateExp2(opc,SIMPNODE_kid0(k0),SIMP_INTCONST(ty, c1+c2));
03447 SIMP_DELETE(SIMPNODE_kid1(k0));
03448 SIMP_DELETE(k0);
03449 SIMP_DELETE(k1);
03450 }
03451 } else if (firstop != OPR_SHL && op == OPR_SHL && c1==c2) {
03452 SHOW_RULE("(j >> c1) << c1");
03453 c2 = ~create_bitmask(c1);
03454 r = SIMPNODE_SimpCreateExp2(OPC_FROM_OPR(OPR_BAND,ty),
03455 SIMPNODE_kid0(k0),
03456 SIMP_INTCONST(ty,c2));
03457 SIMP_DELETE(SIMPNODE_kid1(k0));
03458 SIMP_DELETE(k0);
03459 SIMP_DELETE(k1);
03460 } else if (firstop == OPR_SHL && op == OPR_LSHR && c1==c2) {
03461 SHOW_RULE("(j << c1) LSHR c1");
03462 c2 = create_bitmask(shift_size-c1);
03463 r = SIMPNODE_SimpCreateExp2(OPC_FROM_OPR(OPR_BAND,ty),
03464 SIMPNODE_kid0(k0),
03465 SIMP_INTCONST(ty,c2));
03466 SIMP_DELETE(SIMPNODE_kid1(k0));
03467 SIMP_DELETE(k0);
03468 SIMP_DELETE(k1);
03469 } else if (firstop == OPR_SHL && op == OPR_LSHR && Enable_extract_compose && c1 > c2) {
03470 SHOW_RULE("(j << c1) LSHR c2");
03471 INT16 boffset = c1 - c2;
03472 INT16 bsize = shift_size - c1;
03473 if (bsize < 1) bsize = 1;
03474 r = SIMPNODE_SimpCreateExtract(shift_size == 32 ? OPC_U4EXTRACT_BITS : OPC_U8EXTRACT_BITS,
03475 boffset, bsize,
03476 SIMPNODE_kid0(k0));
03477 SIMP_DELETE(SIMPNODE_kid1(k0));
03478 SIMP_DELETE(k0);
03479 SIMP_DELETE(k1);
03480 } else if (firstop == OPR_SHL && op == OPR_ASHR && c1 == 32 && c2 == 32) {
03481 rty = SIMPNODE_rtype(SIMPNODE_kid0(k0));
03482 if (rty == MTYPE_I4 || rty == MTYPE_U4) {
03483 SHOW_RULE("(j << 32) ASHR 32");
03484 r = SIMPNODE_SimpCreateExp1(OPC_I8I4CVT,SIMPNODE_kid0(k0));
03485 SIMP_DELETE(SIMPNODE_kid1(k0));
03486 SIMP_DELETE(k0);
03487 SIMP_DELETE(k1);
03488 }
03489
03490
03491 } else if (firstop == OPR_SHL && op == OPR_ASHR && Enable_extract_compose && c1 >= c2) {
03492 SHOW_RULE("(j << c1) ASHR c2");
03493 INT16 boffset = c1 - c2;
03494 INT16 bsize = shift_size - c1;
03495 if (bsize < 1) bsize = 1;
03496 r = SIMPNODE_SimpCreateExtract(shift_size == 32 ? OPC_I4EXTRACT_BITS : OPC_I8EXTRACT_BITS,
03497 boffset, bsize,
03498 SIMPNODE_kid0(k0));
03499 SIMP_DELETE(SIMPNODE_kid1(k0));
03500 SIMP_DELETE(k0);
03501 SIMP_DELETE(k1);
03502 }
03503 } else if (firstop == OPR_BAND && op == OPR_SHL &&
03504 SIMP_Is_Constant(SIMPNODE_kid1(k0))) {
03505 c2 = SIMP_Int_ConstVal(SIMPNODE_kid1(k0));
03506
03507 mask = create_bitmask(shift_size-c1);
03508 if ((c2 & mask) == mask) {
03509 SHOW_RULE("(j & mask) << c1");
03510 r = SIMPNODE_SimpCreateExp2(opc,SIMPNODE_kid0(k0),k1);
03511 SIMP_DELETE(SIMPNODE_kid1(k0));
03512 SIMP_DELETE(k0);
03513 return (r);
03514 } else if (Enable_extract_compose && IS_POWER_OF_2(c2+1)) {
03515 SHOW_RULE("(j & mask) << c1 -> COMPOSE");
03516 c2 = wn_simp_code::log2(c2+1);
03517 r = SIMPNODE_SimpCreateDeposit(OPC_FROM_OPR(OPR_COMPOSE_BITS,ty),c1,c2,
03518 SIMP_INTCONST(ty,0),SIMPNODE_kid0(k0));
03519 SIMP_DELETE(SIMPNODE_kid1(k0));
03520 SIMP_DELETE(k0);
03521 return (r);
03522 }
03523 } else if (firstop == OPR_BAND && (op == OPR_ASHR || op == OPR_LSHR) &&
03524 SIMP_Is_Constant(SIMPNODE_kid1(k0)) &&
03525 shift_size == MTYPE_bit_size(OPCODE_rtype(first_opcode))) {
03526 c2 = SIMP_Int_ConstVal(SIMPNODE_kid1(k0));
03527 SHOW_RULE("(j & mask) >> c1");
03528 tmp = SIMPNODE_SimpCreateExp2(opc,SIMPNODE_kid1(k0),SIMPNODE_CopyNode(k1));
03529 r = SIMPNODE_SimpCreateExp2(opc,SIMPNODE_kid0(k0),k1);
03530 r = SIMPNODE_SimpCreateExp2(SIMPNODE_opcode(k0),r,tmp);
03531 SIMP_DELETE(k0);
03532 } else {
03533 rty = get_value_type(k0);
03534 if (rty != ty && ((op == OPR_LSHR)
03535 || (op == OPR_ASHR &&
03536 SIMP_IS_TYPE_UNSIGNED(SIMP_TYPE(k0)) &&
03537 SIMP_TYPE_SIZE(rty) < SIMP_TYPE_SIZE(ty)))) {
03538 if (c1 >= SIMP_TYPE_SIZE(rty)) {
03539 SHOW_RULE("short >> large c1 = 0");
03540 r = SIMP_INTCONST(ty,0);
03541 }
03542 }
03543 }
03544 }
03545 if (r) return (r);
03546
03547
03548 if (SIMPNODE_operator(k1) == OPR_BAND &&
03549 SIMP_Is_Constant(SIMPNODE_kid1(k1)) && ARCH_mask_shift_counts) {
03550 c1 = SIMP_Int_ConstVal(SIMPNODE_kid1(k1));
03551 if ((c1 & (shift_size-1)) == shift_size-1) {
03552 SHOW_RULE ("j shift (X & mask)");
03553 r = SIMPNODE_SimpCreateExp2(opc,k0,SIMPNODE_kid0(k1));
03554 SIMPNODE_DELETE(SIMPNODE_kid1(k1));
03555 SIMPNODE_DELETE(k1);
03556 }
03557 }
03558 return (r);
03559 }
03560
03561
03562
03563
03564
03565
03566
03567
03568
03569
03570
03571
03572 static simpnode cancel_in_relop(OPCODE opc, TYPE_ID ty, simpnode k0, simpnode k1)
03573 {
03574 simpnode r = NULL;
03575 simpnode t;
03576 simpnode dt;
03577 OPERATOR op0,op1,top,mainopr;
03578 char buf[64];
03579 OPCODE kidop;
03580
03581 simpnode x[4],lhs,rhs,del1,del2,del3;
03582 BOOL s[4],s_lhs,s_rhs,pointer_seen;
03583 INT32 i,j,jmax;
03584
03585 op0 = SIMPNODE_operator(k0);
03586 op1 = SIMPNODE_operator(k1);
03587
03588
03589 if (op0 == OPR_NEG && op1 == OPR_NEG) {
03590 SHOW_RULE("-x relop -y");
03591 r = SIMPNODE_SimpCreateExp2(OPCODE_commutative_op(opc),SIMPNODE_kid0(k0),SIMPNODE_kid0(k1));
03592 SIMPNODE_DELETE(k0);
03593 SIMPNODE_DELETE(k1);
03594 return (r);
03595 }
03596
03597
03598 if (op0 == OPR_LDA && op1 == OPR_LDA &&
03599 SIMPNODE_Compare_Symbols(k0,k1) == 0) {
03600 SHOW_RULE("LDA relop LDA");
03601 lhs = SIMP_INTCONST(MTYPE_I8,SIMPNODE_lda_offset(k0));
03602 rhs = SIMP_INTCONST(MTYPE_I8,SIMPNODE_lda_offset(k1));
03603 opc = OPCODE_make_op(OPCODE_operator(opc),MTYPE_I4,MTYPE_I8);
03604 SIMPNODE_DELETE(k0);
03605 SIMPNODE_DELETE(k1);
03606 r = SIMPNODE_SimpCreateExp2(opc,lhs,rhs);
03607 }
03608
03609 if (!Enable_Cfold_Aggressive) return (r);
03610 if (SIMP_IS_TYPE_FLOATING(ty) &&
03611 (!Enable_Cfold_Reassociate || Force_IEEE_Comparisons
03612 || Roundoff_Level < ROUNDOFF_ANY)) return(r);
03613
03614
03615 if (op0 != OPR_ADD && op1 != OPR_ADD && op0 != OPR_SUB && op1 != OPR_SUB) return (r);
03616
03617
03618
03619 if (op0 != OPR_ADD && op0 != OPR_SUB) {
03620
03621 opc = OPCODE_commutative_op(opc);
03622 t = k0; k0 = k1; k1 = t;
03623 top = op0; op0 = op1; op1 = top;
03624 }
03625
03626
03627 if (op0 != OPR_ADD && op1 == OPR_ADD) {
03628
03629 opc = OPCODE_commutative_op(opc);
03630 t = k0; k0 = k1; k1 = t;
03631 top = op0; op0 = op1; op1 = top;
03632 }
03633
03634 mainopr = OPCODE_operator(opc);
03635
03636
03637 s[0] = 0;
03638 s[1] = (op0 == OPR_SUB);
03639 x[0] = SIMPNODE_kid0(k0);
03640 x[1] = SIMPNODE_kid1(k0);
03641
03642 if (op1 == OPR_ADD || op1 == OPR_SUB) {
03643 s[2] = 0;
03644 s[3] = (op1 == OPR_SUB);
03645 x[2] = SIMPNODE_kid0(k1);
03646 x[3] = SIMPNODE_kid1(k1);
03647 jmax = 3;
03648 } else if (op1 == OPR_NEG) {
03649 s[2] = 1;
03650 x[2] = SIMPNODE_kid0(k1);
03651 x[3] = NULL;
03652 jmax = 2;
03653 } else {
03654 s[2] = 0;
03655 x[2] = k1;
03656 x[3] = NULL;
03657 jmax = 2;
03658 }
03659
03660
03661 pointer_seen = FALSE;
03662 if (mainopr != OPR_EQ && mainopr != OPR_NE) {
03663
03664 for (i=0; i <= jmax; i++) {
03665 kidop = SIMPNODE_opcode(x[i]);
03666 if (OPCODE_has_1ty(kidop) || OPCODE_has_2ty(kidop)) {
03667 if (TY_kind (SIMPNODE_ty(x[i])) == KIND_POINTER) {
03668 pointer_seen = TRUE;
03669 break;
03670 }
03671 } else if (OPCODE_operator(kidop) == OPR_LDA) {
03672 pointer_seen = TRUE;
03673 break;
03674 }
03675 }
03676 }
03677
03678
03679 if (SIMP_IS_TYPE_UNSIGNED(ty) && !pointer_seen && !Simp_Fold_Unsigned_Relops &&
03680 (mainopr != OPR_EQ && mainopr != OPR_NE)) return(r);
03681
03682
03683 if ((mainopr != OPR_EQ && mainopr != OPR_NE) &&
03684 SIMP_IS_TYPE_INTEGRAL(ty) && !SIMP_IS_TYPE_UNSIGNED(ty) &&
03685 !Simp_Unsafe_Relops) return (r);
03686
03687
03688
03689 for (i=0; i <= 1; i++) {
03690 for (j=2; j <= jmax; j++) {
03691 if (s[i]==s[j] && (dt = simp_diff_value(x[i],x[j],s[i]))) {
03692
03693
03694 lhs = x[1-i]; s_lhs = s[1-i];
03695 rhs = x[5-j]; s_rhs = s[5-j];
03696 if (!rhs) {
03697 rhs = dt;
03698 if (!s_lhs) {
03699 rhs = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_NEG,ty),rhs);
03700 }
03701 s_rhs = s_lhs;
03702 } else {
03703
03704 if (s_lhs) {
03705 dt = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_NEG,ty),dt);
03706 }
03707 lhs = SIMPNODE_SimpCreateExp2(OPC_FROM_OPR(OPR_ADD,ty),lhs,dt);
03708 }
03709
03710 if (pointer_seen) {
03711
03712
03713
03714
03715 sprintf(buf,"(pointers) x+y relop x+z %2d %2d\n",i,j);
03716 SHOW_RULE(buf);
03717
03718 if (ty == MTYPE_U8) {
03719 opc = OPCODE_make_op(mainopr,OPCODE_rtype(opc),MTYPE_I8);
03720 } else if (ty == MTYPE_U4) {
03721 opc = OPCODE_make_op(mainopr,OPCODE_rtype(opc),MTYPE_I4);
03722 }
03723 if (s_lhs && s_rhs) {
03724 r = SIMPNODE_SimpCreateExp2(opc,rhs,lhs);
03725 } else {
03726 if (s_lhs) {
03727 lhs = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_NEG,ty),lhs);
03728 }
03729 if (s_rhs) {
03730 rhs = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_NEG,ty),rhs);
03731 }
03732 r = SIMPNODE_SimpCreateExp2(opc,lhs,rhs);
03733 }
03734 SIMP_DELETE_TREE(x[i]);
03735 SIMP_DELETE_TREE(x[j]);
03736 SIMP_DELETE(k0);
03737 if (k1 != x[j]) SIMP_DELETE(k1);
03738 return (r);
03739
03740 } else {
03741 sprintf(buf,"x+y relop x+z %2d %2d\n",i,j);
03742 SHOW_RULE(buf);
03743
03744
03745
03746 if (s_lhs && s_rhs) {
03747 r = SIMPNODE_SimpCreateExp2(opc,rhs,lhs);
03748 } else {
03749 if (s_lhs) {
03750 lhs = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_NEG,ty),lhs);
03751 }
03752 if (s_rhs) {
03753 rhs = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_NEG,ty),rhs);
03754 }
03755 r = SIMPNODE_SimpCreateExp2(opc,lhs,rhs);
03756 }
03757 SIMP_DELETE_TREE(x[i]);
03758 SIMP_DELETE_TREE(x[j]);
03759 SIMP_DELETE(k0);
03760 if (k1 != x[j]) SIMP_DELETE(k1);
03761 return (r);
03762 }
03763 }
03764 }
03765 }
03766 if (r) return (r);
03767
03768
03769
03770 if (jmax != 3) return (r);
03771
03772
03773 lhs = NULL;
03774 rhs = NULL;
03775
03776 for (i=0; i <= 1; i++) {
03777 if (s[i] == 0 && (dt = simp_diff_value(k1,x[i],TRUE))) {
03778 lhs = x[1-i];
03779 s_lhs = s[1-i];
03780 del1 = x[i];
03781 del2 = k1;
03782 del3 = k0;
03783 break;
03784 } else if (s[i+2] == 0 && (dt = simp_diff_value(k0,x[i+2],FALSE))) {
03785 rhs = x[3-i];
03786 s_rhs = s[3-i];
03787 del1 = x[i+2];
03788 del2 = k0;
03789 del3 = k1;
03790 break;
03791 }
03792 }
03793 if (lhs || rhs) {
03794 if (!rhs) {
03795 rhs = dt;
03796 s_rhs = 0;
03797 }
03798 if (!lhs) {
03799 lhs = dt;
03800 s_lhs = 0;
03801 }
03802
03803 if (pointer_seen) {
03804
03805
03806
03807
03808 SHOW_RULE("(pointers) x+y relop x");
03809
03810 if (ty == MTYPE_U8) {
03811 opc = OPCODE_make_op(mainopr,OPCODE_rtype(opc),MTYPE_I8);
03812 } else if (ty == MTYPE_U4) {
03813 opc = OPCODE_make_op(mainopr,OPCODE_rtype(opc),MTYPE_I4);
03814 }
03815 if (s_lhs && s_rhs) {
03816 r = SIMPNODE_SimpCreateExp2(opc,rhs,lhs);
03817 } else {
03818 if (s_lhs) {
03819 lhs = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_NEG,ty),lhs);
03820 }
03821 if (s_rhs) {
03822 rhs = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_NEG,ty),rhs);
03823 }
03824 r = SIMPNODE_SimpCreateExp2(opc,lhs,rhs);
03825 }
03826
03827 SIMP_DELETE_TREE(del1);
03828 SIMP_DELETE_TREE(del2);
03829 SIMP_DELETE(del3);
03830 return (r);
03831
03832 } else {
03833 SHOW_RULE(" x+y relop x");
03834
03835
03836 if (s_lhs && s_rhs) {
03837 r = SIMPNODE_SimpCreateExp2(opc,rhs,lhs);
03838 } else {
03839 if (s_lhs) {
03840 lhs = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_NEG,ty),lhs);
03841 }
03842 if (s_rhs) {
03843 rhs = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_NEG,ty),rhs);
03844 }
03845 r = SIMPNODE_SimpCreateExp2(opc,lhs,rhs);
03846 }
03847
03848 SIMP_DELETE_TREE(del1);
03849 SIMP_DELETE_TREE(del2);
03850 SIMP_DELETE(del3);
03851 return (r);
03852 }
03853 }
03854 return (r);
03855 }
03856
03857
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869
03870
03871
03872
03873
03874
03875
03876
03877
03878
03879
03880
03881
03882
03883
03884
03885
03886
03887
03888 static simpnode
03889 simp_eq_neq (OPCODE opc, simpnode k0, simpnode k1, BOOL k0const, BOOL k1const)
03890 {
03891 simpnode r = NULL, expr;
03892 INT64 c1,c2,c3;
03893 TYPE_ID ty;
03894 BOOL iseq;
03895 OPCODE firstop,inv_op;
03896
03897 iseq = (OPCODE_operator(opc) == OPR_EQ);
03898
03899
03900
03901 if (k0const) {
03902 return (r);
03903 }
03904
03905 firstop = SIMPNODE_opcode(k0);
03906 inv_op = get_inverse_relop(firstop);
03907 ty = OPCODE_rtype(firstop);
03908
03909 if (k1const && SIMP_IS_TYPE_INTEGRAL(ty)) {
03910 c1 = SIMP_Int_ConstVal(k1);
03911 if (c1 == 0 || c1 == 1) {
03912 if (((is_logop(firstop) && (ty == OPCODE_rtype(opc))) || inv_op) &&
03913 ((iseq && c1==1) || (!iseq && c1==0))){
03914
03915
03916
03917
03918 SHOW_RULE("x reloporlogop y ==1,!=0");
03919 r = SIMPNODE_SimpCreateExp2(
03920 OPCODE_make_op(OPCODE_operator(firstop),
03921 OPCODE_rtype(opc),
03922 OPCODE_desc(firstop)),
03923 SIMPNODE_kid0(k0),SIMPNODE_kid1(k0));
03924 SIMP_DELETE(k0);
03925 SIMP_DELETE(k1);
03926 } else if (is_logop(firstop) &&
03927 ((iseq && c1==0) || (!iseq && c1==1))) {
03928
03929
03930
03931
03932 SHOW_RULE("x logop y ==0,!=1");
03933 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_LNOT,ty), k0);
03934 SIMP_DELETE(k1);
03935 } else if (inv_op &&
03936 ((iseq && c1==0) || (!iseq && c1==1))) {
03937
03938
03939
03940
03941 if (!SIMP_IS_TYPE_FLOATING(OPCODE_desc(inv_op)) ||
03942 !Force_IEEE_Comparisons) {
03943 SHOW_RULE("x relop y ==0,!=1");
03944 OPCODE inv_relop = OPCODE_make_op(OPCODE_operator(inv_op),
03945 OPCODE_rtype(opc),
03946 OPCODE_desc(inv_op));
03947 r = SIMPNODE_SimpCreateExp2(inv_relop,
03948 SIMPNODE_kid0(k0),
03949 SIMPNODE_kid1(k0));
03950 SIMP_DELETE(k1);
03951 SIMP_DELETE(k0);
03952 }
03953 } else if (iseq &&
03954 (c1 == 0) &&
03955 (OPCODE_operator(firstop)==OPR_BAND) &&
03956 (SIMPNODE_operator(SIMPNODE_kid0(k0))==OPR_BNOT) &&
03957 SIMP_Is_Constant(SIMPNODE_kid1(k0))) {
03958 c2 = SIMP_Int_ConstVal(SIMPNODE_kid1(k0));
03959 expr = SIMPNODE_kid0(SIMPNODE_kid0(k0));
03960 if ((c2 != 0) && IS_POWER_OF_2(c2)) {
03961 SHOW_RULE(" (~j & c2) == 0 (j & c2) != 0 if c2 is a power of 2 ");
03962
03963 r = SIMPNODE_SimpCreateExp2(firstop, expr, SIMPNODE_kid1(k0));
03964 r = SIMPNODE_SimpCreateExp2(get_inverse_relop(opc),
03965 r,k1);
03966 SIMP_DELETE(SIMPNODE_kid0(k0));
03967 SIMP_DELETE(k0);
03968
03969 }
03970 }
03971
03972
03973
03974
03975
03976
03977
03978 else if (c1 == 0 && OPCODE_operator(firstop)==OPR_LDA) {
03979 ST_IDX base_idx;
03980 INT64 offset;
03981 LDA_FLAGS l;
03982 l = get_lda_info(k0,offset,base_idx);
03983 if ((l & LDA_CANNOT_BE_ZERO) != 0) {
03984
03985
03986 if (iseq) {
03987 SHOW_RULE("&x == 0");
03988 r = SIMP_INTCONST(OPCODE_rtype(opc), 0);
03989 } else {
03990 SHOW_RULE("&x != 0");
03991 r = SIMP_INTCONST(OPCODE_rtype(opc), 1);
03992 }
03993 SIMP_DELETE_TREE(k0);
03994 SIMP_DELETE_TREE(k1);
03995 }
03996 }
03997 }
03998
03999
04000 if (r) return (r);
04001
04002
04003 if ((!ARCH_has_bit_tests) &&
04004 (c1 == 0) &&
04005 (OPCODE_operator(firstop)==OPR_BAND) &&
04006 SIMP_Is_Constant(SIMPNODE_kid1(k0)) &&
04007 (SIMP_Int_ConstVal(SIMPNODE_kid1(k0))==1)) {
04008 simpnode k0k0 = SIMPNODE_kid0(k0);
04009 if (((SIMPNODE_operator(k0k0) == OPR_LSHR) ||
04010 (SIMPNODE_operator(k0k0) == OPR_ASHR)) &&
04011 SIMP_Is_Constant(SIMPNODE_kid1(k0k0))) {
04012 ty = SIMPNODE_rtype(k0k0);
04013 c2 = MTYPE_bit_size(ty) - 1 - SIMP_Int_ConstVal(SIMPNODE_kid1(k0k0));
04014 SHOW_RULE("(x>>c1)&1 ==,!= 0");
04015
04016 r = SIMPNODE_SimpCreateExp2(MTYPE_bit_size(ty) == 32 ? OPC_I4SHL : OPC_I8SHL,
04017 SIMPNODE_kid0(k0k0),SIMP_INTCONST(MTYPE_I4,c2));
04018 if (MTYPE_is_unsigned(ty)) ty = MTYPE_complement(ty);
04019 OPCODE newopc = OPCODE_make_op(iseq ? OPR_GE : OPR_LT,
04020 OPCODE_rtype(opc),
04021 ty);
04022 r = SIMPNODE_SimpCreateExp2(newopc,r,SIMP_INTCONST(ty,0));
04023 SIMP_DELETE(SIMPNODE_kid1(k0k0));
04024 SIMP_DELETE(k0k0);
04025 SIMP_DELETE(k1);
04026 SIMP_DELETE(SIMPNODE_kid1(k0));
04027 SIMP_DELETE(k0);
04028 }
04029 } else if ((OPCODE_operator(firstop)==OPR_BIOR ||
04030 OPCODE_operator(firstop)==OPR_BAND) &&
04031 SIMP_Is_Constant(SIMPNODE_kid1(k0))) {
04032 c2 = SIMP_Int_ConstVal(SIMPNODE_kid1(k0));
04033
04034
04035
04036
04037
04038
04039 if (((c1 & ~c2)!=0 && OPCODE_operator(firstop)==OPR_BAND) ||
04040 ((c2 & ~c1)!=0 && OPCODE_operator(firstop)==OPR_BIOR)) {
04041 if (iseq) {
04042 c2 = 0;
04043 } else {
04044 c2 = 1;
04045 }
04046 SHOW_RULE("(j & c2) == c1 ->0 et al");
04047 r = SIMP_INTCONST(OPCODE_rtype(opc), c2);
04048 SIMP_DELETE_TREE(k0);
04049 SIMP_DELETE_TREE(k1);
04050 }
04051 } else if ((OPCODE_operator(firstop)==OPR_ADD ||
04052 OPCODE_operator(firstop)==OPR_SUB) &&
04053 SIMP_Is_Constant(SIMPNODE_kid1(k0))) {
04054 c2 = SIMP_Int_ConstVal(SIMPNODE_kid1(k0));
04055
04056
04057
04058 if (OPCODE_operator(firstop)==OPR_ADD) {
04059 c2 = -c2;
04060 }
04061 c3 = c1 + c2;
04062 SHOW_RULE("(j -+ c2) == c1");
04063 r = SIMPNODE_SimpCreateExp2(opc,SIMPNODE_kid0(k0),
04064 SIMP_INTCONST(OPCODE_rtype(firstop), c3));
04065 SIMP_DELETE(SIMPNODE_kid1(k0));
04066 SIMP_DELETE(k0);
04067 SIMP_DELETE(k1);
04068 } else if (OPCODE_operator(firstop)==OPR_SUB &&
04069 SIMP_Is_Constant(SIMPNODE_kid0(k0))) {
04070
04071
04072
04073 c2 = SIMP_Int_ConstVal(SIMPNODE_kid0(k0));
04074 c3 = c2 - c1;
04075 SHOW_RULE("(j -+ c2) == c1");
04076 r = SIMPNODE_SimpCreateExp2(opc,SIMPNODE_kid1(k0),
04077 SIMP_INTCONST(OPCODE_rtype(firstop), c3));
04078 SIMP_DELETE(SIMPNODE_kid0(k0));
04079 SIMP_DELETE(k0);
04080 SIMP_DELETE(k1);
04081 } else if (OPCODE_operator(firstop)==OPR_MPY &&
04082 SIMP_Is_Constant(SIMPNODE_kid1(k0))) {
04083
04084
04085
04086 c2 = SIMP_Int_ConstVal(SIMPNODE_kid1(k0));
04087 if (c2 != 0) {
04088 if ((c1/c2)*c2 == c1) {
04089 SHOW_RULE("(j * c2) == c1 divides");
04090 r = SIMPNODE_SimpCreateExp2(opc,SIMPNODE_kid0(k0),
04091 SIMP_INTCONST(OPCODE_rtype(firstop), c1/c2));
04092 SIMP_DELETE(SIMPNODE_kid1(k0));
04093 SIMP_DELETE(k0);
04094 SIMP_DELETE(k1);
04095 } else {
04096 SHOW_RULE("(j * c2) == c1 nodivide");
04097 if (iseq) {
04098 c2 = 0;
04099 } else {
04100 c2 = 1;
04101 }
04102 r = SIMP_INTCONST(OPCODE_rtype(opc), c2);
04103 SIMP_DELETE_TREE(k0);
04104 SIMP_DELETE_TREE(k1);
04105 }
04106 }
04107 }
04108 }
04109
04110
04111 if (!Enable_Cfold_Aggressive || r) return (r);
04112
04113
04114 if (!Force_IEEE_Comparisons || SIMP_IS_TYPE_INTEGRAL(OPCODE_desc(opc))) {
04115 if (SIMPNODE_Simp_Compare_Trees(k0,k1)==0) {
04116 if (iseq) {
04117 c1 = 1;
04118 SHOW_RULE("x==x");
04119 } else {
04120 c1 = 0;
04121 SHOW_RULE("x!=x");
04122 }
04123 r = SIMP_INTCONST(OPCODE_rtype(opc), c1);
04124 SIMP_DELETE_TREE(k0);
04125 SIMP_DELETE_TREE(k1);
04126 }
04127 }
04128 if (r) return (r);
04129
04130 if (OPCODE_operator(firstop)==OPR_LDA &&
04131 SIMPNODE_operator(k1) == OPR_LDA) {
04132 YESNOMAYBE lda_comp;
04133 lda_comp = LDA_Equal_Address(k0,k1);
04134 if (lda_comp == YES) {
04135 SHOW_RULE("&x == &y (true)");
04136 r = SIMP_INTCONST(OPCODE_rtype(opc), iseq);
04137 SIMP_DELETE_TREE(k0);
04138 SIMP_DELETE_TREE(k1);
04139 } else if (lda_comp == NO) {
04140 SHOW_RULE("&x == &y (false)");
04141 r = SIMP_INTCONST(OPCODE_rtype(opc), !iseq);
04142 SIMP_DELETE_TREE(k0);
04143 SIMP_DELETE_TREE(k1);
04144 }
04145 }
04146 if (r) return (r);
04147
04148 r = cancel_in_relop(opc, OPCODE_desc(opc), k0, k1);
04149
04150 return (r);
04151 }
04152
04153
04154
04155
04156
04157
04158
04159
04160
04161
04162
04163
04164
04165
04166
04167
04168
04169
04170
04171
04172
04173
04174
04175
04176
04177
04178
04179
04180
04181
04182 static simpnode simp_relop(OPCODE opc,
04183 simpnode k0, simpnode k1, BOOL k0const, BOOL k1const)
04184 {
04185 simpnode r = NULL;
04186 INT64 c1,c2,c3;
04187 TYPE_ID ty, rtyp;
04188 BOOL c1min,c1max;
04189 BOOL add_fold_ok;
04190 OPERATOR op;
04191 OPCODE newopc;
04192
04193 op = OPCODE_operator(opc);
04194
04195
04196
04197 if (k0const) {
04198 return (r);
04199 }
04200
04201 ty = OPCODE_desc(opc);
04202 rtyp = OPCODE_rtype(opc);
04203
04204
04205 add_fold_ok = (!SIMP_IS_TYPE_UNSIGNED(ty) || Simp_Fold_Unsigned_Relops) &&
04206 Simp_Unsafe_Relops;
04207
04208 if (!SIMP_IS_TYPE_UNSIGNED(ty) &&
04209 (SIMP_IS_TYPE_UNSIGNED(SIMPNODE_rtype(k0)) ||
04210 SIMP_IS_TYPE_UNSIGNED(SIMPNODE_rtype(k1)))) {
04211 add_fold_ok = Simp_Fold_Unsigned_Relops;
04212 }
04213
04214
04215 if (k1const && SIMP_IS_TYPE_INTEGRAL(ty)) {
04216 c1 = SIMP_Int_ConstVal(k1);
04217 c1min = FALSE;
04218 c1max = FALSE;
04219 switch (ty) {
04220 case MTYPE_I4:
04221 c1min = (c1 == INT32_MIN);
04222 c1max = (c1 == INT32_MAX);
04223 break;
04224 case MTYPE_I8:
04225 c1min = (c1 == 0x8000000000000000LL);
04226 c1max = (c1 == 0x7fffffffffffffffLL);
04227 break;
04228 case MTYPE_U4:
04229 c1min = (c1 == 0);
04230 c1max = (c1 == UINT32_MAX);
04231 break;
04232 case MTYPE_U8:
04233 c1min = (c1 == 0);
04234 c1max = (c1 == 0xffffffffffffffffLL);
04235 break;
04236 }
04237 if (c1min && op == OPR_LT) {
04238 SHOW_RULE("x < MIN");
04239 r = SIMP_INTCONST(rtyp, 0);
04240 } else if (c1min && op == OPR_GE) {
04241 SHOW_RULE("x >= MIN");
04242 r = SIMP_INTCONST(rtyp, 1);
04243 } else if (c1max && op == OPR_GT) {
04244 SHOW_RULE("x > MAX");
04245 r = SIMP_INTCONST(rtyp, 0);
04246 } else if (c1max && op == OPR_LE) {
04247 SHOW_RULE("x <= MAX");
04248 r = SIMP_INTCONST(rtyp, 1);
04249 }
04250 if (r) {
04251 SIMP_DELETE_TREE(k0);
04252 SIMP_DELETE_TREE(k1);
04253 return (r);
04254 }
04255
04256
04257 if ((SIMPNODE_operator(k0) == OPR_ADD) &&
04258 SIMP_Is_Constant(SIMPNODE_kid1(k0)) &&
04259 add_fold_ok) {
04260 c2 = SIMP_Int_ConstVal(SIMPNODE_kid1(k0));
04261 if (is_sub_ok(&c3,c1,c2,ty)) {
04262 SHOW_RULE ("j + c2 relop c1");
04263 r = SIMPNODE_SimpCreateExp2(opc,SIMPNODE_kid0(k0),
04264 SIMP_INTCONST(ty,c3));
04265 SIMP_DELETE(k1);
04266 SIMP_DELETE(SIMPNODE_kid1(k0));
04267 SIMP_DELETE(k0);
04268 }
04269 } else if (SIMPNODE_operator(k0) == OPR_SUB && add_fold_ok) {
04270 if (SIMP_Is_Constant(SIMPNODE_kid1(k0))) {
04271 c2 = SIMP_Int_ConstVal(SIMPNODE_kid1(k0));
04272 if (is_add_ok(&c3,c1,c2,ty)) {
04273 SHOW_RULE ("j - c2 relop c1");
04274 r = SIMPNODE_SimpCreateExp2(opc,SIMPNODE_kid0(k0),
04275 SIMP_INTCONST(ty,c3));
04276 SIMP_DELETE(k1);
04277 SIMP_DELETE(SIMPNODE_kid1(k0));
04278 SIMP_DELETE(k0);
04279 }
04280 } else if (SIMP_Is_Constant(SIMPNODE_kid0(k0))) {
04281 c2 = SIMP_Int_ConstVal(SIMPNODE_kid0(k0));
04282 if (is_sub_ok(&c3,c2,c1,ty)) {
04283 SHOW_RULE ("c2 - j relop c1");
04284 r = SIMPNODE_SimpCreateExp2(OPCODE_commutative_op(opc),SIMPNODE_kid1(k0),
04285 SIMP_INTCONST(ty,c3));
04286 SIMP_DELETE(k1);
04287 SIMP_DELETE(SIMPNODE_kid0(k0));
04288 SIMP_DELETE(k0);
04289 }
04290 }
04291 } else if (SIMPNODE_operator(k0)==OPR_MPY &&
04292 SIMP_Is_Constant(SIMPNODE_kid1(k0)) &&
04293 add_fold_ok) {
04294
04295
04296
04297 c2 = SIMP_Int_ConstVal(SIMPNODE_kid1(k0));
04298 if (c2!=0) {
04299 BOOL divides=FALSE;
04300 BOOL sign_c3;
04301 c3 = c1/c2;
04302 sign_c3 = (c1 ^ c2) < 0;
04303 if (c1 == c3*c2) divides = TRUE;
04304 newopc = (c2 > 0) ? opc : OPCODE_commutative_op(opc);
04305 if (divides) {
04306 SHOW_RULE("(j * c2) == c1 (divides)");
04307 r = SIMPNODE_SimpCreateExp2(newopc,SIMPNODE_kid0(k0),
04308 SIMP_INTCONST(ty, c3));
04309 SIMP_DELETE(SIMPNODE_kid1(k0));
04310 SIMP_DELETE(k0);
04311 SIMP_DELETE(k1);
04312 } else {
04313
04314 if ((op == OPR_LT && c1 > 0) ||
04315 (op == OPR_GT && c1 < 0) ||
04316 (op == OPR_LE && c1 < 0) ||
04317 (op == OPR_GE && c1 > 0)) {
04318
04319 if (sign_c3) {
04320 c3 -= 1;
04321 } else {
04322 c3 += 1;
04323 }
04324 }
04325 SHOW_RULE("(j * c2) == c1 (no divides)");
04326 r = SIMPNODE_SimpCreateExp2(newopc,SIMPNODE_kid0(k0),
04327 SIMP_INTCONST(ty, c3));
04328 SIMP_DELETE(SIMPNODE_kid1(k0));
04329 SIMP_DELETE(k0);
04330 SIMP_DELETE(k1);
04331 }
04332 }
04333 }
04334 }
04335
04336 if (r) return (r);
04337
04338
04339
04340
04341
04342
04343
04344
04345
04346
04347 if (SIMP_IS_TYPE_INTEGRAL(ty) && add_fold_ok &&
04348 SIMPNODE_operator(k1) == OPR_ADD &&
04349 SIMP_Is_Constant(SIMPNODE_kid1(k1))) {
04350 c1 = SIMP_Int_ConstVal(SIMPNODE_kid1(k1));
04351 if (c1==1 && op == OPR_LT) {
04352 SHOW_RULE("i < j+1");
04353 r = SIMPNODE_SimpCreateExp2(OPCODE_make_op(OPR_LE,rtyp,ty),k0,SIMPNODE_kid0(k1));
04354 }
04355 if (c1==1 && op == OPR_GE) {
04356 SHOW_RULE("i >= j+1");
04357 r = SIMPNODE_SimpCreateExp2(OPCODE_make_op(OPR_GT,rtyp,ty),k0,SIMPNODE_kid0(k1));
04358 }
04359 if (c1==-1 && op == OPR_GT) {
04360 SHOW_RULE("i > j-1");
04361 r = SIMPNODE_SimpCreateExp2(OPCODE_make_op(OPR_GE,rtyp,ty),k0,SIMPNODE_kid0(k1));
04362 }
04363 if (c1==-1 && op == OPR_LE) {
04364 SHOW_RULE("i <= j-1");
04365 r = SIMPNODE_SimpCreateExp2(OPCODE_make_op(OPR_LT,rtyp,ty),k0,SIMPNODE_kid0(k1));
04366 }
04367 if (r) {
04368 SIMP_DELETE(SIMPNODE_kid1(k1));
04369 SIMP_DELETE(k1);
04370 return (r);
04371 }
04372 }
04373
04374
04375
04376
04377
04378
04379
04380
04381 if (SIMP_IS_TYPE_INTEGRAL(ty) && add_fold_ok &&
04382 SIMPNODE_operator(k0) == OPR_ADD &&
04383 Simp_Unsafe_Relops &&
04384 SIMP_Is_Constant(SIMPNODE_kid1(k0))) {
04385 c1 = SIMP_Int_ConstVal(SIMPNODE_kid1(k0));
04386 if (c1==-1 && op == OPR_LT) {
04387 SHOW_RULE("j-1 < i");
04388 r = SIMPNODE_SimpCreateExp2(OPCODE_make_op(OPR_LE,rtyp,ty),SIMPNODE_kid0(k0),k1);
04389 }
04390 if (c1==-1 && op == OPR_GE) {
04391 SHOW_RULE("j-1 >= i");
04392 r = SIMPNODE_SimpCreateExp2(OPCODE_make_op(OPR_GT,rtyp,ty),SIMPNODE_kid0(k0),k1);
04393 }
04394 if (c1==1 && op == OPR_GT) {
04395 SHOW_RULE("j+1 > i");
04396 r = SIMPNODE_SimpCreateExp2(OPCODE_make_op(OPR_GE,rtyp,ty),SIMPNODE_kid0(k0),k1);
04397 }
04398 if (c1==1 && op == OPR_LE) {
04399 SHOW_RULE("j+1 <= i");
04400 r = SIMPNODE_SimpCreateExp2(OPCODE_make_op(OPR_LT,rtyp,ty),SIMPNODE_kid0(k0),k1);
04401 }
04402 if (r) {
04403 SIMP_DELETE(SIMPNODE_kid1(k0));
04404 SIMP_DELETE(k0);
04405 return (r);
04406 }
04407 }
04408
04409
04410
04411 if (!Enable_Cfold_Aggressive || r) return (r);
04412
04413 if (!Force_IEEE_Comparisons || SIMP_IS_TYPE_INTEGRAL(ty)) {
04414 if (SIMPNODE_Simp_Compare_Trees(k0,k1)==0) {
04415 if (op == OPR_LE || op == OPR_GE) {
04416 c1 = 1;
04417 SHOW_RULE("x<=x, x>=x");
04418 } else {
04419 c1 = 0;
04420 SHOW_RULE("x<x, x>x");
04421 }
04422 r = SIMP_INTCONST(rtyp, c1);
04423 SIMP_DELETE_TREE(k0);
04424 SIMP_DELETE_TREE(k1);
04425 }
04426 }
04427
04428 if (r) return (r);
04429 r = cancel_in_relop(opc, ty, k0, k1);
04430
04431 return (r);
04432 }
04433
04434
04435
04436
04437
04438
04439
04440
04441
04442
04443
04444
04445
04446
04447
04448
04449 #include "wn_simp_ftable.h"
04450
04451
04452
04453
04454
04455
04456
04457
04458
04459 static simpnode Fold2_Into_Select(OPCODE opc, simpnode k0, simpnode k1)
04460 {
04461 simpnode r = NULL;
04462 simpnode sk1,sk2,kt;
04463
04464 if (SIMPNODE_operator(k0)==OPR_SELECT) {
04465 sk1 = SIMPNODE_kid1(k0);
04466 sk2 = SIMPNODE_kid(k0,2);
04467 if (SIMP_Is_Constant(sk1) &&
04468 SIMP_Is_Constant(sk2)) {
04469 kt = SIMPNODE_CopyNode(k1);
04470 r = SIMPNODE_SimpCreateExp3(OPC_FROM_OPR(OPR_SELECT,OPCODE_rtype(opc)),
04471 SIMPNODE_kid0(k0),
04472 SIMPNODE_SimpCreateExp2(opc,sk1,k1),
04473 SIMPNODE_SimpCreateExp2(opc,sk2,kt));
04474 SHOW_RULE("SELECT(x,c1,c2) op c0");
04475 }
04476 } else if (SIMPNODE_operator(k1)==OPR_SELECT) {
04477 sk1 = SIMPNODE_kid1(k1);
04478 sk2 = SIMPNODE_kid(k1,2);
04479 if (SIMP_Is_Constant(sk1) &&
04480 SIMP_Is_Constant(sk2)) {
04481 kt = SIMPNODE_CopyNode(k0);
04482 r = SIMPNODE_SimpCreateExp3(OPC_FROM_OPR(OPR_SELECT,OPCODE_rtype(opc)),
04483 SIMPNODE_kid0(k1),
04484 SIMPNODE_SimpCreateExp2(opc,k0,sk1),
04485 SIMPNODE_SimpCreateExp2(opc,kt,sk2));
04486 SHOW_RULE("co op SELECT(x,c1,c2)");
04487 }
04488 }
04489 return (r);
04490 }
04491
04492
04493
04494 static simpnode SIMPNODE_ConstantFold1(OPCODE opc, simpnode k0)
04495 {
04496 simpnode r = NULL;
04497 TCON c0,c1;
04498 BOOL folded;
04499
04500 if (SIMP_Is_Flt_Constant(k0)) {
04501 c0 = SIMP_Flt_ConstVal(k0);
04502 } else {
04503 c0 = Host_To_Targ(SIMPNODE_rtype(k0),SIMP_Int_ConstVal(k0));
04504 }
04505
04506 #ifndef WN_SIMP_WORKING_ON_WHIRL
04507
04508
04509 if (OPCODE_operator(opc) == OPR_CVTL ||
04510 OPCODE_operator(opc) == OPR_PARM ||
04511 (Split_64_Bit_Int_Ops &&
04512 OPCODE_operator(opc) == OPR_CVT &&
04513 MTYPE_bit_size(OPCODE_rtype(opc)) == 64 &&
04514 MTYPE_bit_size(OPCODE_desc(opc)) == 32)) {
04515
04516 return r;
04517 } else {
04518 c1 = Host_To_Targ(MTYPE_I8,0);
04519 }
04520 #else
04521
04522 c1 = Host_To_Targ(MTYPE_I8,0);
04523 #endif
04524
04525
04526 c0 = Targ_WhirlOp(opc,c0,c1,&folded);
04527 if (folded) {
04528 SHOW_RULE("constant fold 1");
04529 if (SIMP_IS_TYPE_INTEGRAL(TCON_ty(c0))) {
04530 r = SIMP_INTCONST(TCON_ty(c0),Targ_To_Host(c0));
04531 } else {
04532 r = SIMPNODE_CreateFloatconstFromTcon(c0);
04533 }
04534 SIMP_DELETE(k0);
04535 }
04536 return (r);
04537 }
04538
04539 static simpnode SIMPNODE_ConstantFold2(OPCODE opc, simpnode k0, simpnode k1)
04540 {
04541 simpnode r = NULL;
04542 TCON c0,c1;
04543 BOOL folded;
04544
04545 if (SIMP_Is_Flt_Constant(k0)) {
04546 c0 = SIMP_Flt_ConstVal(k0);
04547 } else {
04548 c0 = Host_To_Targ(SIMPNODE_rtype(k0),SIMP_Int_ConstVal(k0));
04549 }
04550 if (SIMP_Is_Flt_Constant(k1)) {
04551 c1 = SIMP_Flt_ConstVal(k1);
04552 } else {
04553 c1 = Host_To_Targ(SIMPNODE_rtype(k1),SIMP_Int_ConstVal(k1));
04554 }
04555
04556 c0 = Targ_WhirlOp(opc,c0,c1,&folded);
04557 if (folded) {
04558 SHOW_RULE("constant fold 2");
04559 if (SIMP_IS_TYPE_INTEGRAL(TCON_ty(c0))) {
04560 r = SIMP_INTCONST(TCON_ty(c0),Targ_To_Host(c0));
04561 } else {
04562 r = SIMPNODE_CreateFloatconstFromTcon(c0);
04563 }
04564 SIMP_DELETE(k0);
04565 SIMP_DELETE(k1);
04566 }
04567 return (r);
04568 }
04569
04570
04571
04572 static simpnode SIMPNODE_SimplifyExp2_h(OPCODE opc, simpnode k0, simpnode k1)
04573 {
04574 BOOL k0const, k1const;
04575 OPERATOR op;
04576 OPCODE canon_opc;
04577 simpnode result=NULL;
04578
04579 simpnode (*simp_func)(OPCODE opc, simpnode k0, simpnode k1,
04580 BOOL k0const, BOOL k1const);
04581
04582 if (!SIMPNODE_enable || !OPCODE_is_expression(opc)) return (result);
04583 if (!SIMPNODE_simp_initialized) SIMPNODE_Simplify_Initialize();
04584
04585 op = OPCODE_operator(opc);
04586 simp_func = simplify_function_table[op];
04587 k0const = SIMP_Is_Constant(k0);
04588 k1const = SIMP_Is_Constant(k1);
04589
04590 if (k0const && k1const) {
04591 result = SIMPNODE_ConstantFold2(opc, k0, k1);
04592 return (result);
04593 }
04594
04595
04596
04597 if (op != OPR_MINMAX && op != OPR_DIVREM) {
04598 if (k0const || k1const) {
04599 result = Fold2_Into_Select(opc, k0, k1);
04600 if (result) return (result);
04601 }
04602 }
04603
04604 if (Simp_Canonicalize) {
04605
04606
04607
04608
04609
04610
04611
04612
04613
04614
04615
04616
04617
04618
04619
04620 if (k0const &&
04621 (canon_opc = OPCODE_commutative_op(opc)) != 0) {
04622
04623 SHOW_RULE("commute constant operand");
04624 result = SIMPNODE_SimpCreateExp2(canon_opc, k1, k0);
04625 return (result);
04626 }
04627
04628
04629
04630
04631
04632
04633
04634
04635
04636 if (!k0const && !k1const &&
04637 (canon_opc = OPCODE_commutative_op(opc)) &&
04638 Enable_Cfold_Aggressive) {
04639 if (SIMPNODE_Simp_Compare_Trees(k0,k1) == 1) {
04640 SHOW_RULE("commute operand");
04641 result = SIMPNODE_SimpCreateExp2(canon_opc, k1, k0);
04642 return(result);
04643 }
04644 }
04645
04646
04647
04648
04649
04650
04651
04652
04653
04654
04655
04656
04657
04658
04659
04660
04661
04662
04663
04664
04665 if (is_ok_to_reassociate(opc)) {
04666 if (k1const && (SIMPNODE_opcode(k0) == opc) &&
04667 SIMP_Is_Constant(SIMPNODE_kid1(k0))) {
04668 SHOW_RULE("reassociate 1");
04669 result = SIMPNODE_SimpCreateExp2(opc, SIMPNODE_kid0(k0),
04670 SIMPNODE_SimpCreateExp2(opc, SIMPNODE_kid1(k0), k1));
04671 SIMP_DELETE(k0);
04672 return (result);
04673 }
04674
04675 if (!k1const &&
04676 SIMPNODE_opcode(k0) == opc &&
04677 SIMP_Is_Constant(SIMPNODE_kid1(k0))) {
04678 TY_IDX tas_idx = 0;
04679 simpnode t0;
04680 SHOW_RULE("reassociate 2a");
04681
04682
04683
04684
04685 if(SIMPNODE_operator(k0) == OPR_LDA &&
04686 Type_Is_Shared_Ptr(ST_type(SIMPNODE_st((k0))))) {
04687 tas_idx = ST_type(SIMPNODE_st(k0));
04688 } else if(SIMPNODE_operator(k1) == OPR_LDA &&
04689 Type_Is_Shared_Ptr(ST_type(SIMPNODE_st(k1))) ) {
04690 tas_idx = ST_type(SIMPNODE_st(k1));
04691 }
04692
04693 k1 = SIMPNODE_SimpCreateExp2(opc, SIMPNODE_kid0(k0), k1);
04694 if (tas_idx) {
04695 OPCODE opc = OPCODE_make_op(OPR_TAS, Pointer_Mtype, MTYPE_V);
04696 t0 = SIMPNODE_SimpCreateExp1(opc, k1);
04697 WN_set_ty((WN*)t0, tas_idx);
04698 k1 = t0;
04699 SHOW_RULE("tas after reassociate2a");
04700 }
04701 result = SIMPNODE_SimpCreateExp2(opc ,k1, SIMPNODE_kid1(k0));
04702 SIMP_DELETE(k0);
04703 return (result);
04704 }
04705
04706 if (!k1const &&
04707 SIMPNODE_opcode(k1) == opc &&
04708 SIMP_Is_Constant(SIMPNODE_kid1(k1))) {
04709 SHOW_RULE("reassociate 2b");
04710 result = SIMPNODE_SimpCreateExp2(opc,
04711 SIMPNODE_SimpCreateExp2(opc, SIMPNODE_kid0(k1), k0),
04712 SIMPNODE_kid1(k1));
04713 SIMP_DELETE(k1);
04714 return (result);
04715 }
04716
04717 if (SIMPNODE_opcode(k0) == opc &&
04718 SIMPNODE_opcode(k1) == opc &&
04719 SIMP_Is_Constant(SIMPNODE_kid1(k0)) &&
04720 SIMP_Is_Constant(SIMPNODE_kid1(k1))) {
04721
04722 SHOW_RULE("reassociate 3");
04723 result = SIMPNODE_SimpCreateExp2(opc, SIMPNODE_kid0(k0),SIMPNODE_kid0(k1));
04724 result = SIMPNODE_SimpCreateExp2(opc, result,
04725 SIMPNODE_SimpCreateExp2(opc,SIMPNODE_kid1(k0),SIMPNODE_kid1(k1)));
04726 SIMP_DELETE(k0);
04727 SIMP_DELETE(k1);
04728 return (result);
04729 }
04730 }
04731 }
04732 if (simp_func) {
04733 result = simp_func(opc, k0, k1, k0const, k1const);
04734 } else {
04735 result = NULL;
04736 }
04737
04738 return (result);
04739 }
04740
04741
04742 simpnode SIMPNODE_SimplifyExp2(OPCODE opc, simpnode k0, simpnode k1)
04743 {
04744 simpnode result;
04745 result = SIMPNODE_SimplifyExp2_h(opc, k0,k1);
04746 SHOW_TREE(opc,k0,k1,result);
04747 return (result);
04748 }
04749
04750
04751 simpnode SIMPNODE_SimplifyExp1(OPCODE opc, simpnode k0)
04752 {
04753 OPERATOR op;
04754 simpnode result=NULL;
04755 simpnode k1,k2;
04756
04757 simpnode (*simp_func)(OPCODE opc, simpnode k0, simpnode k1,
04758 BOOL k0const, BOOL k1const);
04759
04760 if (!SIMPNODE_enable || !OPCODE_is_expression(opc)) return (result);
04761 if (!SIMPNODE_simp_initialized) SIMPNODE_Simplify_Initialize();
04762
04763 op = OPCODE_operator(opc);
04764
04765
04766 #undef DEBUG_IGNORE_PARENS
04767 #ifdef DEBUG_IGNORE_PARENS
04768 if (op == OPR_PAREN) return k0;
04769 #endif
04770
04771
04772
04773
04774
04775
04776 if (SIMPNODE_operator(k0) == OPR_SELECT && op != OPR_PARM) {
04777 k1 = SIMPNODE_kid1(k0);
04778 k2 = SIMPNODE_kid(k0,2);
04779
04780
04781
04782
04783 if (SIMP_Is_Constant(k1) && SIMP_Is_Constant(k2)) {
04784 result = SIMPNODE_SimpCreateExp3(OPC_FROM_OPR(OPR_SELECT,OPCODE_rtype(opc)),
04785 SIMPNODE_kid0(k0),
04786 SIMPNODE_SimpCreateExp1(opc,k1),
04787 SIMPNODE_SimpCreateExp1(opc,k2));
04788 SHOW_RULE("OP(SELECT(x,c1,c2))");
04789 }
04790 } else {
04791 simp_func = simplify_function_table[op];
04792 if (SIMP_Is_Constant(k0)) {
04793 result = SIMPNODE_ConstantFold1(opc, k0);
04794 } else if (simp_func) {
04795 result = simp_func(opc, k0, NULL, FALSE, FALSE);
04796 } else {
04797 result = NULL;
04798 }
04799 }
04800
04801 SHOW_TREE(opc,k0,NULL,result);
04802 return (result);
04803 }
04804
04805
04806
04807
04808
04809
04810
04811
04812
04813
04814
04815
04816
04817
04818
04819
04820
04821
04822
04823 simpnode simp_cvtl(OPCODE opc, INT16 cvtl_bits, simpnode k0)
04824 {
04825 simpnode r=NULL,k1,k2;
04826 TYPE_ID source_ty,dest_ty;
04827 INT16 s_size,d_size,k0_bits;
04828 INT64 cval,mask;
04829 OPERATOR opr0;
04830
04831 source_ty = SIMPNODE_rtype(k0);
04832 dest_ty = OPCODE_rtype(opc);
04833
04834
04835 if (SIMP_Is_Constant(k0)) {
04836 BOOL folded = FALSE;
04837 TCON c0,c1;
04838 #ifndef WN_SIMP_WORKING_ON_WHIRL
04839 if (Split_64_Bit_Int_Ops &&
04840 MTYPE_bit_size(dest_ty) == 64 &&
04841 MTYPE_bit_size(source_ty) == 32) {
04842
04843 }
04844 else
04845 #endif
04846 {
04847 c0 = Host_To_Targ(source_ty,SIMP_Int_ConstVal(k0));
04848 c1 = Host_To_Targ(MTYPE_I8,cvtl_bits);
04849 c0 = Targ_WhirlOp(opc,c0,c1,&folded);
04850 }
04851 if (folded) {
04852 SHOW_RULE("constant fold cvtl");
04853 r = SIMP_INTCONST(dest_ty,Targ_To_Host(c0));
04854 SIMP_DELETE(k0);
04855 return (r);
04856 }
04857 } else if (SIMPNODE_operator(k0) == OPR_SELECT) {
04858 k1 = SIMPNODE_kid1(k0);
04859 k2 = SIMPNODE_kid(k0,2);
04860
04861
04862
04863
04864 if (SIMP_Is_Constant(k1) || SIMP_Is_Constant(k2) ||
04865 SIMPNODE_opcode(k1) == opc || SIMPNODE_opcode(k2) == opc) {
04866 simpnode t_k1 = SIMPNODE_SimplifyCvtl(opc,cvtl_bits,k1);
04867 simpnode t_k2 = SIMPNODE_SimplifyCvtl(opc,cvtl_bits,k2);
04868 r = SIMPNODE_SimpCreateExp3(OPC_FROM_OPR(OPR_SELECT,OPCODE_rtype(opc)),
04869 SIMPNODE_kid0(k0),
04870 (t_k1) ? t_k1 : SIMPNODE_SimpCreateCvtl(opc,cvtl_bits,k1),
04871 (t_k2) ? t_k2 : SIMPNODE_SimpCreateCvtl(opc,cvtl_bits,k2));
04872
04873 SHOW_RULE("CVTL(SELECT(x,c1,c2))");
04874 }
04875 } else if (SIMPNODE_opcode(k0) == opc) {
04876
04877 k0_bits = SIMPNODE_cvtl_bits(k0);
04878 if (k0_bits <= cvtl_bits) {
04879 SHOW_RULE("CVTL(n1,CVTL(n2,k0)), n2 <= n1");
04880 r = k0;
04881 } else {
04882 SHOW_RULE("CVTL(n1,CVTL(n2,k0)), n2 > n1");
04883 r = SIMPNODE_SimpCreateCvtl(opc,cvtl_bits,SIMPNODE_kid0(k0));
04884 }
04885 } else if (SIMPNODE_operator(k0) == OPR_BAND &&
04886 SIMP_Is_Constant(SIMPNODE_kid1(k0))) {
04887 cval = SIMP_Int_ConstVal(SIMPNODE_kid1(k0));
04888 mask = (1ll << cvtl_bits) - 1ll;
04889 if ((mask & cval) == mask) {
04890 SHOW_RULE("cvtl(x&c1) -> cvtl(x)");
04891 r = SIMPNODE_SimpCreateCvtl(opc,cvtl_bits,SIMPNODE_kid0(k0));
04892 SIMP_DELETE(SIMPNODE_kid1(k0));
04893 SIMP_DELETE(k0);
04894 }
04895 } else {
04896
04897 s_size = SIMP_TYPE_SIZE(source_ty);
04898 d_size = SIMP_TYPE_SIZE(dest_ty);
04899
04900 if (s_size == d_size && s_size == cvtl_bits) {
04901 SHOW_RULE("CVTL(n, k0) -> k0");
04902 r = k0;
04903 }
04904 }
04905
04906 if (r) return (r);
04907
04908
04909
04910
04911
04912
04913
04914
04915
04916 opr0 = SIMPNODE_operator(k0);
04917 switch (opr0) {
04918 case OPR_NEG:
04919 case OPR_BNOT:
04920 case OPR_LNOT:
04921 k1 = SIMPNODE_kid0(k0);
04922 if (SIMPNODE_opcode(k1) == opc &&
04923 SIMPNODE_cvtl_bits(k1) >= cvtl_bits) {
04924 SHOW_RULE("CVTL n (op CVTL n (X))");
04925 r = SIMPNODE_SimpCreateCvtl(opc,cvtl_bits,
04926 SIMPNODE_SimpCreateExp1(SIMPNODE_opcode(k0),
04927 SIMPNODE_kid0(k1)));
04928 SIMP_DELETE(k1);
04929 SIMP_DELETE(k0);
04930 } else if (opr0 == OPR_LNOT) {
04931
04932 r = k0;
04933 }
04934 break;
04935
04936 #if 0 // this rule is wrong because of the number 0x8000 in 16 bits;
04937
04938
04939 case OPR_ABS:
04940 k1 = SIMPNODE_kid0(k0);
04941 if (SIMPNODE_opcode(k1) == opc &&
04942 SIMPNODE_cvtl_bits(k1) == cvtl_bits) {
04943 SHOW_RULE("CVTL n (ABS CVTL n (X))");
04944 r = k0;
04945 }
04946 break;
04947 #endif
04948
04949 case OPR_LT:
04950 case OPR_LE:
04951 case OPR_GT:
04952 case OPR_GE:
04953 case OPR_EQ:
04954 case OPR_NE:
04955 case OPR_LIOR:
04956 case OPR_LAND:
04957
04958 r = k0;
04959 break;
04960
04961 case OPR_ADD:
04962 case OPR_SUB:
04963 case OPR_MPY:
04964 case OPR_BIOR:
04965 case OPR_BXOR:
04966 case OPR_BAND:
04967 case OPR_SHL:
04968 k1 = SIMPNODE_kid0(k0);
04969 k2 = SIMPNODE_kid1(k0);
04970 if (SIMPNODE_opcode(k1) == opc &&
04971 SIMPNODE_cvtl_bits(k1) >= cvtl_bits &&
04972 SIMPNODE_opcode(k2) == opc &&
04973 SIMPNODE_cvtl_bits(k2) >= cvtl_bits) {
04974 SHOW_RULE("CVTL n (CVTL n (X) op CVTL(y))");
04975 r = SIMPNODE_SimpCreateCvtl(opc,cvtl_bits,
04976 SIMPNODE_SimpCreateExp2(SIMPNODE_opcode(k0),
04977 SIMPNODE_kid0(k1),
04978 SIMPNODE_kid0(k2)));
04979 SIMP_DELETE(k2);
04980 SIMP_DELETE(k1);
04981 SIMP_DELETE(k0);
04982 } else if (SIMPNODE_opcode(k1) == opc &&
04983 SIMPNODE_cvtl_bits(k1) >= cvtl_bits) {
04984 SHOW_RULE("CVTL n (CVTL n (X) op y)");
04985 r = SIMPNODE_SimpCreateCvtl(opc,cvtl_bits,
04986 SIMPNODE_SimpCreateExp2(SIMPNODE_opcode(k0),
04987 SIMPNODE_kid0(k1),
04988 k2));
04989 SIMP_DELETE(k1);
04990 SIMP_DELETE(k0);
04991 } else if (SIMPNODE_opcode(k2) == opc &&
04992 SIMPNODE_cvtl_bits(k2) >= cvtl_bits && opr0 != OPR_SHL) {
04993 SHOW_RULE("CVTL n (X op CVTL n (y))");
04994 r = SIMPNODE_SimpCreateCvtl(opc,cvtl_bits,
04995 SIMPNODE_SimpCreateExp2(SIMPNODE_opcode(k0),
04996 k1,
04997 SIMPNODE_kid0(k2)));
04998 SIMP_DELETE(k2);
04999 SIMP_DELETE(k0);
05000 }
05001 break;
05002 default:
05003 break;
05004 }
05005 return (r);
05006 }
05007
05008 simpnode SIMPNODE_SimplifyCvtl(OPCODE opc, INT16 cvtl_bits, simpnode k0)
05009 {
05010 simpnode result = NULL;
05011 if (!SIMPNODE_enable) return (result);
05012 if (!SIMPNODE_simp_initialized) SIMPNODE_Simplify_Initialize();
05013
05014 result = simp_cvtl(opc,cvtl_bits,k0);
05015
05016 if (result) {
05017 SHOW_TREE(opc,k0,(simpnode) cvtl_bits, result);
05018 }
05019 return (result);
05020 }
05021
05022
05023
05024
05025
05026
05027
05028
05029
05030
05031
05032
05033
05034
05035
05036 simpnode SIMPNODE_SimplifyExp3(OPCODE opc, simpnode k0, simpnode k1,
05037 simpnode k2)
05038 {
05039 simpnode r = NULL;
05040 OPCODE k0op;
05041
05042 if (!SIMPNODE_enable) return (r);
05043 if (!SIMPNODE_simp_initialized) SIMPNODE_Simplify_Initialize();
05044
05045
05046 if (OPCODE_operator(opc) != OPR_SELECT && OPCODE_operator(opc) != OPR_CSELECT) return (r);
05047
05048 k0op = SIMPNODE_opcode(k0);
05049 if (SIMP_Is_Int_Constant(k0)) {
05050 if (SIMP_Int_ConstVal(k0) == 0) {
05051 SHOW_RULE("SELECT(FALSE,x,y)");
05052 r = k2;
05053 SIMP_DELETE_TREE(k1);
05054 } else {
05055 SHOW_RULE("SELECT(TRUE,x,y)");
05056 r = k1;
05057 SIMP_DELETE_TREE(k2);
05058 }
05059 SIMP_DELETE_TREE(k0);
05060 } else if (SIMP_Is_Int_Constant(k1) &&
05061 SIMP_Is_Int_Constant(k2) &&
05062 SIMPNODE_operator(k0) != OPR_CAND &&
05063 SIMPNODE_operator(k0) != OPR_CIOR) {
05064 if (SIMP_Int_ConstVal(k1) == 1 &&
05065 SIMP_Int_ConstVal(k2) == 0) {
05066 if (get_inverse_relop(k0op) != OPCODE_UNKNOWN ||
05067 OPCODE_rtype(k0op) == MTYPE_B) {
05068 SHOW_RULE("SELECT(boolexpr,1,0)");
05069 r = k0;
05070 SIMP_DELETE_TREE(k1);
05071 SIMP_DELETE_TREE(k2);
05072 } else {
05073 TYPE_ID k0_rtype = OPCODE_rtype(k0op);
05074 SHOW_RULE("SELECT(expr,1,0)");
05075 r = SIMPNODE_SimpCreateExp2(OPCODE_make_op(OPR_NE, k0_rtype, k0_rtype),
05076 k0, SIMP_INTCONST(k0_rtype, 0));
05077 SIMP_DELETE_TREE(k1);
05078 SIMP_DELETE_TREE(k2);
05079 }
05080 } else if (SIMP_Int_ConstVal(k1) == 0 &&
05081 SIMP_Int_ConstVal(k2) == 1) {
05082 SHOW_RULE("SELECT(expr,0,1)");
05083 r = SIMPNODE_SimpCreateExp1(OPC_FROM_OPR(OPR_LNOT,OPCODE_rtype(k0op)),k0);
05084 SIMP_DELETE_TREE(k1);
05085 SIMP_DELETE_TREE(k2);
05086 }
05087 if (r) {
05088 const TYPE_ID opc_rtype = OPCODE_rtype(opc);
05089 if (OPCODE_rtype(k0op) == MTYPE_B && opc_rtype != MTYPE_B)
05090 r = SIMPNODE_SimpCreateExp1(
05091 OPCODE_make_op(OPR_CVT, opc_rtype, MTYPE_B), r);
05092 return (r);
05093 }
05094 }
05095 if (r == NULL && Enable_Cfold_Aggressive) {
05096 if (SIMPNODE_Simp_Compare_Trees(k1,k2)==0) {
05097 SHOW_RULE("SELECT(x,y,y)");
05098 r = k1;
05099 SIMP_DELETE_TREE(k0);
05100 SIMP_DELETE_TREE(k2);
05101 }
05102 }
05103
05104 return (r);
05105 }
05106
05107
05108
05109
05110
05111
05112
05113
05114 #define MAX_INTRINSIC_ARGS 6
05115 simpnode SIMPNODE_SimplifyIntrinsic(OPCODE opc, UINT32 intrinsic, INT32 n, simpnode k[])
05116 {
05117 simpnode r = NULL;
05118 TCON c[MAX_INTRINSIC_ARGS],c0;
05119 BOOL allconst;
05120 BOOL folded;
05121 INT i;
05122 INT64 ival;
05123 TYPE_ID ty;
05124 simpnode kid;
05125
05126 if (!SIMPNODE_enable) return (r);
05127 if (!SIMPNODE_simp_initialized) SIMPNODE_Simplify_Initialize();
05128
05129 if (OPCODE_operator(opc) != OPR_INTRINSIC_OP) return(r);
05130
05131
05132 if (n > MAX_INTRINSIC_ARGS) return (r);
05133 allconst = TRUE;
05134 for (i=0; (i < n) && allconst; i++) {
05135 kid = k[i];
05136 if (SIMPNODE_operator(kid) == OPR_PARM) {
05137 kid = SIMPNODE_kid0(kid);
05138 }
05139 if (SIMP_Is_Constant(kid)) {
05140 if (SIMP_Is_Flt_Constant(kid)) {
05141 c[i] = SIMP_Flt_ConstVal(kid);
05142 } else {
05143 c[i] = Host_To_Targ(SIMPNODE_rtype(kid),SIMP_Int_ConstVal(kid));
05144 }
05145 } else {
05146 allconst = FALSE;
05147 }
05148 }
05149 if (allconst) {
05150 SHOW_RULE("intrinsic fold");
05151 c0 = Targ_IntrinsicOp(intrinsic,c,&folded);
05152 if (folded) {
05153 if (SIMP_IS_TYPE_INTEGRAL(TCON_ty(c0))) {
05154 ival = Targ_To_Host(c0);
05155 ty = TCON_ty(c0);
05156
05157 if (ty == MTYPE_I1 || ty == MTYPE_I2) {
05158 ty = MTYPE_I4;
05159 } else if (ty == MTYPE_U1 || ty == MTYPE_U2) {
05160 ty = MTYPE_U4;
05161 }
05162 r = SIMP_INTCONST(ty,ival);
05163 } else {
05164 r = SIMPNODE_CreateFloatconstFromTcon(c0);
05165 }
05166
05167 if (n >= 2) {
05168 SHOW_TREE(opc,k[0],k[1],r);
05169 } else {
05170 SHOW_TREE(opc,k[0],NULL,r);
05171 }
05172
05173 for (i=0; i<n; i++) {
05174 SIMP_DELETE(k[i]);
05175 }
05176 }
05177 }
05178 return (r);
05179 }
05180
05181
05182
05183 #ifdef WN_SIMP_WORKING_ON_WHIRL
05184
05185
05186
05187
05188
05189
05190
05191 simpnode SIMPNODE_SimplifyIload(OPCODE opc, WN_OFFSET offset,
05192 TY_IDX ty, UINT field_id, TY_IDX load_addr_ty,
05193 simpnode addr)
05194 {
05195 simpnode r = NULL;
05196 INT64 lda_offset,new_offset;
05197
05198
05199 if (!SIMPNODE_enable || !WN_Simp_Fold_ILOAD) return (r);
05200 if (!SIMPNODE_simp_initialized) SIMPNODE_Simplify_Initialize();
05201
05202
05203 if (SIMPNODE_operator(addr) == OPR_LDA
05204 #ifndef TARG_MIPS
05205 && ST_class(SIMPNODE_st_idx(addr)) != CLASS_FUNC
05206 #endif
05207 ) {
05208 lda_offset = SIMPNODE_lda_offset(addr);
05209 if (is_add_ok(&new_offset,offset,lda_offset,MTYPE_I4)) {
05210 SHOW_RULE("ILOAD(LDA)->LDID");
05211 r = WN_CreateLdid(OPCODE_operator(opc) == OPR_ILOAD ? OPR_LDID : OPR_LDBITS,
05212 OPCODE_rtype(opc),
05213 OPCODE_desc(opc),
05214 new_offset,
05215 SIMPNODE_st_idx(addr),
05216 ty,
05217 field_id);
05218 SIMP_DELETE(addr);
05219 }
05220 }
05221 return (r);
05222 }
05223
05224 simpnode SIMPNODE_SimplifyIstore(OPCODE opc, WN_OFFSET offset,
05225 TY_IDX ty, UINT field_id, simpnode value,
05226 simpnode addr)
05227 {
05228 simpnode r = NULL;
05229 INT64 lda_offset,new_offset;
05230 TY_IDX pointed;
05231
05232
05233 if (!SIMPNODE_enable || !WN_Simp_Fold_ILOAD) return (r);
05234 if (!SIMPNODE_simp_initialized) SIMPNODE_Simplify_Initialize();
05235
05236
05237 if (SIMPNODE_operator(addr) == OPR_LDA) {
05238 lda_offset = SIMPNODE_lda_offset(addr);
05239 if (is_add_ok(&new_offset,offset,lda_offset,MTYPE_I4)) {
05240 SHOW_RULE("ISTORE(LDA)->STID");
05241 pointed = TY_pointed(ty);
05242 DevAssert(pointed, ("TY_pointed of ISTORE type is NULL"));
05243 r = WN_CreateStid(OPCODE_operator(opc) == OPR_ISTORE ? OPR_STID : OPR_STBITS,
05244 OPCODE_rtype(opc),
05245 OPCODE_desc(opc),
05246 new_offset,
05247 SIMPNODE_st_idx(addr),
05248 pointed,
05249 value,
05250 field_id);
05251 SIMP_DELETE(addr);
05252 }
05253 }
05254 return (r);
05255 }
05256
05257
05258
05259 simpnode SIMPNODE_SimplifyPstore(OPCODE opc, WN_OFFSET offset,
05260 TY_IDX ty, UINT field_id, simpnode value,
05261 simpnode addr)
05262 {
05263 simpnode r = NULL;
05264 INT64 lda_offset,new_offset;
05265 TY_IDX pointed;
05266
05267
05268 if (!SIMPNODE_enable || !WN_Simp_Fold_ILOAD) return (r);
05269 if (!SIMPNODE_simp_initialized) SIMPNODE_Simplify_Initialize();
05270
05271
05272 if (SIMPNODE_operator(addr) == OPR_LDA) {
05273 lda_offset = SIMPNODE_lda_offset(addr);
05274 if (is_add_ok(&new_offset,offset,lda_offset,MTYPE_I4)) {
05275 SHOW_RULE("PSTORE(LDA)->PSTID");
05276 pointed = TY_pointed(ty);
05277 DevAssert(pointed, ("TY_pointed of PSTORE type is NULL"));
05278 r = WN_CreatePStid(OPCODE_operator(opc) == OPR_PSTORE ? OPR_PSTID : OPR_STBITS,
05279 OPCODE_rtype(opc),
05280 OPCODE_desc(opc),
05281 new_offset,
05282 SIMPNODE_st_idx(addr),
05283 pointed,
05284 value,
05285 field_id);
05286 SIMP_DELETE(addr);
05287 }
05288 }
05289 return (r);
05290 }
05291 #endif
05292