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