00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 #ifdef USE_PCH
00064 #include "opt_pch.h"
00065 #endif // USE_PCH
00066 #pragma hdrstop
00067
00068
00069 #ifdef _KEEP_RCS_ID
00070 #define opt_fold_CXX "opt_fold.cxx"
00071 static char *rcs_id = opt_fold_CXX"$Revision: 1.9 $";
00072 #endif
00073
00074 #define __STDC_LIMIT_MACROS
00075 #include <stdint.h>
00076 #include "defs.h"
00077 #include "errors.h"
00078 #include "erglob.h"
00079 #include "tracing.h"
00080 #include "config_opt.h"
00081
00082 #include "opt_wn.h"
00083 #include "opcode_core.h"
00084 #include "wn_map.h"
00085 #include "opt_sym.h"
00086 #include "targ_const.h"
00087 #include "stab.h"
00088 #include "const.h"
00089 #include "opt_util.h"
00090 #include "opt_config.h"
00091 #include "opt_fold.h"
00092 #include "opt_htable.h"
00093
00094
00095
00096
00097 static CODEREP *CR_Create(OPCODE, INT, CODEREP *k0, CODEREP *k1 = NULL,
00098 CODEREP *k2 = NULL);
00099 static CODEREP *CR_SimpCreateExp1(OPCODE, CODEREP *);
00100 static CODEREP *CR_SimpCreateExp2(OPCODE, CODEREP *, CODEREP *);
00101 static OPCODE CR_opcode(CODEREP *);
00102 static OPERATOR CR_operator(CODEREP *);
00103 static ST *CR_st(CODEREP *);
00104 static TY_IDX CR_ty(CODEREP *);
00105 static void CR_set_kid0(CODEREP *, CODEREP *);
00106 static CODEREP *CR_kid0(CODEREP *);
00107 static CODEREP *CR_kid(CODEREP *, INT);
00108 static INT32 CR_kid_count(CODEREP *);
00109 static CODEREP *Combine_bits_any_nzero_test(CODEREP *);
00110 static CODEREP *Combine_bits_all_zero_test(CODEREP *);
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 static CODEMAP *fold_htable;
00144
00145
00146
00147 static BOOL fold_trace;
00148
00149 void
00150 Initialize_CR_simp(CODEMAP *htable)
00151 {
00152 fold_htable = htable;
00153 }
00154
00155
00156 CODEREP *
00157 FOLD::Fold_Expr(CODEREP *cr)
00158 {
00159 if (!WOPT_Enable_Fold2const)
00160 return NOHASH;
00161
00162 #ifdef KEY
00163 if (cr->Kind() == CK_IVAR)
00164 return CR_Simplify_Iload(cr);
00165 #endif
00166
00167 if (cr->Kind() != CK_OP)
00168 return NOHASH;
00169
00170 return CR_Simplify_Expr(cr);
00171 }
00172
00173
00174 CODEREP *
00175 FOLD::Fold_Tree(CODEREP *cr)
00176 {
00177 if (!WOPT_Enable_Fold2const)
00178 return NOHASH;
00179
00180 if (cr->Kind() != CK_OP)
00181 return NOHASH;
00182
00183 return CR_Simplify_Tree(cr);
00184 }
00185
00186
00187
00188 FOLD::FOLD(void)
00189 {
00190 fold_trace = Get_Trace(TP_GLOBOPT, FOLD_DUMP_FLAG);
00191 }
00192
00193
00194
00195 void
00196 FOLD::Print(const char *str, const CODEREP *cr)
00197 {
00198 if (fold_trace)
00199 { fprintf(TFile,"Fold_Expr: %s:\n",str);
00200 if (cr)
00201 cr->Print(0,TFile);
00202 else
00203 fprintf(TFile,"NULL\n");
00204 fflush(TFile);
00205 }
00206 }
00207
00208
00209
00210
00211
00212
00213 static CODEREP *
00214 CR_Create(OPCODE op, INT nkids, CODEREP *k0, CODEREP *k1, CODEREP *k2)
00215 {
00216 CODEREP *cr = Alloc_stack_cr(nkids+IVAR_EXTRA_NODE_CNT);
00217 CODEREP *retv = NULL;
00218 const OPERATOR oper = OPCODE_operator(op);
00219
00220 if (OPCODE_is_leaf(op)) {
00221 if (oper == OPR_LDID) {
00222 if (fold_trace)
00223 fprintf(TFile,"CR_Create, LDID\n");
00224 } else if (oper == OPR_LDBITS) {
00225 if (fold_trace)
00226 fprintf(TFile,"CR_Create, LDBITS\n");
00227 } else if (oper == OPR_LDA) {
00228 if (fold_trace)
00229 fprintf(TFile,"CR_Create, LDA\n");
00230 } else if (oper == OPR_INTCONST) {
00231 if (fold_trace)
00232 fprintf(TFile,"CR_Create, INT const\n");
00233 } else if (oper == OPR_CONST) {
00234 if (fold_trace)
00235 fprintf(TFile,"CR_Create, FP const\n");
00236 } else
00237 FmtAssert(FALSE,("CR_Create, unknown leaf opcode %s",OPCODE_name(op)));
00238 } else if (oper == OPR_ILOAD) {
00239 if (fold_trace)
00240 fprintf(TFile,"CR_Create, ILOAD\n");
00241 } else if (oper == OPR_ILDBITS) {
00242 if (fold_trace)
00243 fprintf(TFile,"CR_Create, ILDBITS\n");
00244 } else if (oper == OPR_MLOAD) {
00245 if (fold_trace)
00246 fprintf(TFile,"CR_Create, MLOAD\n");
00247 } else {
00248 Is_True(nkids == 1 || nkids == 2 || nkids == 3,
00249 ("CR_Create, can't handle nkids=%d",nkids));
00250 if (fold_trace)
00251 fprintf(TFile,"CR_Create, %s, nkids=%d\n",OPCODE_name(op),nkids);
00252 cr->Init_op(op,nkids);
00253 cr->Set_opnd(0,k0);
00254 if (nkids >= 2)
00255 cr->Set_opnd(1,k1);
00256 if (nkids == 3)
00257 cr->Set_opnd(2,k2);
00258 retv = fold_htable->Hash_Op(cr);
00259 }
00260 Is_True(retv,("CR_Create, needs work"));
00261 return retv;
00262 }
00263
00264 static void
00265 show_tree(OPCODE opc, CODEREP *k0, CODEREP *k1, CODEREP *r)
00266 {
00267 if (fold_trace) {
00268 fprintf(TFile,"\nBefore:\n");
00269 k0->Print(0,TFile);
00270 if (OPCODE_operator(opc) != OPR_CVTL) {
00271 if (k1)
00272 k1->Print(0,TFile);
00273 fprintf(TFile,"%s\n",OPCODE_name(opc));
00274 } else
00275 fprintf(TFile,"%s %ld\n",OPCODE_name(opc),(INTPS) k1);
00276 fprintf(TFile,"=====\nAfter:\n");
00277 r->Print(0,TFile);
00278 fprintf(TFile,"-----------------------------------------------------\n");
00279 }
00280 }
00281
00282
00283
00284
00285 CODEREP *
00286 FOLD::CR_Simplify_Tree(CODEREP *cr)
00287 {
00288
00289 OPCODE op = SIMPNODE_opcode(cr);
00290 OPERATOR opr= OPCODE_operator(op);
00291 CODEREP *k0, *k1, *k2, *r = NULL, *result;
00292 INT numkids = SIMPNODE_kid_count(cr), i;
00293 BOOL found = FALSE;
00294
00295 if (!WOPT_Enable_CRSIMP || cr->Is_isop_flag_set(ISOP_FOLD_TREE_VISITED))
00296 return NOHASH;
00297
00298 if (opr == OPR_INTRINSIC_OP
00299 #ifdef KEY
00300 || opr == OPR_PURE_CALL_OP
00301 #endif
00302 ) {
00303 for (i=0; i<numkids; i++) {
00304 k0 = CR_Simplify_Tree(cr->Opnd(i));
00305 if (k0 == NOHASH)
00306 k0 = cr->Opnd(i);
00307 else if (k0 != cr->Opnd(i))
00308 found = TRUE;
00309 cr->Set_opnd(i,k0);
00310 }
00311 #ifdef KEY
00312 if (opr == OPR_PURE_CALL_OP)
00313 result = NULL;
00314 else
00315 #endif
00316 result = SIMPNODE_SimplifyIntrinsic(op, SIMPNODE_intrinsic(cr), numkids,
00317 cr->Opnd_ptr());
00318 if (result) {
00319 CODEREP *tmp = Alloc_stack_cr(numkids+IVAR_EXTRA_NODE_CNT);
00320 tmp->Copy(*result);
00321 result = fold_htable->Rehash(tmp);
00322 } else if (found) {
00323 cr->Set_coderep_id(0);
00324 result = fold_htable->Rehash(cr);
00325 }
00326 else
00327 result = NOHASH;
00328 } else if (numkids == 0) {
00329 result = NOHASH;
00330 } else if (numkids == 1) {
00331 CODEREP *kid = SIMPNODE_kid0(cr);
00332 k0 = CR_Simplify_Tree(kid);
00333 if (k0 == NOHASH)
00334 k0 = kid;
00335 else if (k0 != kid)
00336 found = TRUE;
00337 if ( opr != OPR_CVTL )
00338 r = SIMPNODE_SimplifyExp1(op, k0);
00339 else
00340 r = SIMPNODE_SimplifyCvtl(op, cr->Offset(), k0);
00341 if (r) {
00342 SIMPNODE_DELETE(cr);
00343 result = r;
00344 } else {
00345 if (found) {
00346 CODEREP *tmp = Alloc_stack_cr(numkids+IVAR_EXTRA_NODE_CNT);
00347 tmp->Copy(*cr);
00348 CR_set_kid0(tmp,k0);
00349 result = fold_htable->Rehash(tmp);
00350 } else
00351 result = NOHASH;
00352 }
00353 } else if (numkids == 2) {
00354 k0 = CR_Simplify_Tree(cr->Opnd(0));
00355 if (k0 == NULL)
00356 k0 = cr->Opnd(0);
00357 else if (k0 != cr->Opnd(0))
00358 found = TRUE;
00359
00360 k1 = CR_Simplify_Tree(cr->Opnd(1));
00361 if (k1 == NULL)
00362 k1 = cr->Opnd(1);
00363 else if (k1 != cr->Opnd(1))
00364 found = TRUE;
00365
00366 r = SIMPNODE_SimplifyExp2(op, k0, k1);
00367 if (r) {
00368 SIMPNODE_DELETE(cr);
00369 result = r;
00370 } else {
00371 if (found) {
00372 CODEREP *tmp = Alloc_stack_cr(numkids+IVAR_EXTRA_NODE_CNT);
00373 tmp->Copy(*cr);
00374 tmp->Set_opnd(0,k0);
00375 tmp->Set_opnd(1,k1);
00376 result = fold_htable->Rehash(tmp);
00377 } else
00378 result = NOHASH;
00379 }
00380 } else if (numkids == 3) {
00381 k0 = CR_Simplify_Tree(cr->Opnd(0));
00382 if (k0 == NULL)
00383 k0 = cr->Opnd(0);
00384 else if (k0 != cr->Opnd(0))
00385 found = TRUE;
00386
00387 k1 = CR_Simplify_Tree(cr->Opnd(1));
00388 if (k1 == NULL)
00389 k1 = cr->Opnd(1);
00390 else if (k1 != cr->Opnd(1))
00391 found = TRUE;
00392
00393 k2 = CR_Simplify_Tree(cr->Opnd(2));
00394 if (k2 == NULL)
00395 k2 = cr->Opnd(2);
00396 else if (k2 != cr->Opnd(2))
00397 found = TRUE;
00398
00399 r = SIMPNODE_SimplifyExp3(op, k0, k1, k2);
00400 if (r) {
00401 SIMPNODE_DELETE(cr);
00402 result = r;
00403 } else {
00404 if (found) {
00405 CODEREP *tmp = Alloc_stack_cr(numkids+IVAR_EXTRA_NODE_CNT);
00406 tmp->Copy(*cr);
00407 tmp->Set_opnd(0,k0);
00408 tmp->Set_opnd(1,k1);
00409 tmp->Set_opnd(2,k2);
00410 result = fold_htable->Rehash(tmp);
00411 } else
00412 result = NOHASH;
00413 }
00414 } else {
00415 for (i=0; i<numkids; i++) {
00416 k0 = CR_Simplify_Tree(cr->Opnd(i));
00417 if (k0 == NULL)
00418 k0 = cr->Opnd(i);
00419 else if (k0 != cr->Opnd(i))
00420 found = TRUE;
00421 cr->Set_opnd(i,k0);
00422 }
00423 if (found) {
00424 cr->Set_coderep_id(0);
00425 result = fold_htable->Rehash(cr);
00426 } else
00427 result =NOHASH;
00428 }
00429 return result;
00430 }
00431
00432
00433
00434
00435
00436
00437
00438 CODEREP *
00439 FOLD::CR_Simplify_Expr(CODEREP *cr)
00440 {
00441
00442 OPCODE op = SIMPNODE_opcode(cr);
00443 OPERATOR opr = OPCODE_operator(op);
00444 CODEREP *k0, *k1, *k2, *r = NULL, *result;
00445 INT numkids = SIMPNODE_kid_count(cr);
00446 BOOL found = FALSE;
00447
00448 if (!WOPT_Enable_CRSIMP || cr->Is_isop_flag_set(ISOP_FOLD_EXPR_VISITED))
00449 return NOHASH;
00450
00451 if (opr == OPR_INTRINSIC_OP) {
00452
00453 result = SIMPNODE_SimplifyIntrinsic(op, SIMPNODE_intrinsic(cr), numkids,
00454 cr->Opnd_ptr());
00455 if (result) {
00456 CODEREP *tmp = Alloc_stack_cr(numkids+IVAR_EXTRA_NODE_CNT);
00457 tmp->Copy(*result);
00458 result = fold_htable->Rehash(tmp);
00459 } else
00460 result = NOHASH;
00461
00462 #ifdef KEY
00463 } else if (opr == OPR_PURE_CALL_OP) {
00464 result = NOHASH;
00465 #endif
00466 } else if (numkids == 1) {
00467
00468 CODEREP *k0 = SIMPNODE_kid0(cr);
00469 found = check_convert(cr, &k0, 0);
00470 #ifdef TARG_X8664
00471
00472
00473
00474 if ( op == OPC_F8SQRT && SIMPNODE_opcode(k0) == OPC_F8RECIP )
00475 return NOHASH;
00476 #endif
00477
00478
00479
00480
00481
00482
00483
00484 if ((opr == OPR_EXTRACT_BITS || opr == OPR_COMPOSE_BITS) &&
00485 SIMPNODE_operator(k0) == OPR_SELECT) {
00486 return NOHASH;
00487 }
00488
00489 if ( opr != OPR_CVTL )
00490 r = SIMPNODE_SimplifyExp1(op, k0);
00491 else
00492 r = SIMPNODE_SimplifyCvtl(op, cr->Offset(), k0);
00493 if (r) {
00494 SIMPNODE_DELETE(cr);
00495 result = r;
00496 } else {
00497 if (found) {
00498 CODEREP *tmp = Alloc_stack_cr(numkids+IVAR_EXTRA_NODE_CNT);
00499 tmp->Copy(*cr);
00500 tmp->Set_opnd(0,k0);
00501 result = fold_htable->Rehash(tmp);
00502 } else
00503 result = NOHASH;
00504 }
00505
00506 } else if (numkids == 2) {
00507
00508 k0 = cr->Opnd(0);
00509 found = check_convert(cr, &k0, 0);
00510 k1 = cr->Opnd(1);
00511 found |= check_convert(cr, &k1, 1);
00512 r = SIMPNODE_SimplifyExp2(op, k0, k1);
00513 if (r) {
00514 SIMPNODE_DELETE(cr);
00515 result = r;
00516 } else {
00517 if (found) {
00518 CODEREP *tmp = Alloc_stack_cr(numkids+IVAR_EXTRA_NODE_CNT);
00519 tmp->Copy(*cr);
00520 tmp->Set_opnd(0,k0);
00521 tmp->Set_opnd(1,k1);
00522 result = fold_htable->Rehash(tmp);
00523 } else
00524 #ifndef KEY
00525 result = NOHASH;
00526 #else // bug 8581
00527 result = Combine_bits_any_nzero_test(cr);
00528 if (result == NOHASH)
00529 result = Combine_bits_all_zero_test(cr);
00530 #endif
00531 }
00532
00533 } else if (numkids == 3) {
00534 k0 = cr->Opnd(0);
00535 found = check_convert(cr, &k0, 0);
00536 k1 = cr->Opnd(1);
00537 found |= check_convert(cr, &k1, 1);
00538 k2 = cr->Opnd(2);
00539 found |= check_convert(cr, &k2, 2);
00540 r = SIMPNODE_SimplifyExp3(op, k0, k1, k2);
00541 if (r) {
00542 SIMPNODE_DELETE(cr);
00543 result = r;
00544 } else {
00545 if (found) {
00546 CODEREP *tmp = Alloc_stack_cr(numkids+IVAR_EXTRA_NODE_CNT);
00547 tmp->Copy(*cr);
00548 tmp->Set_opnd(0,k0);
00549 tmp->Set_opnd(1,k1);
00550 tmp->Set_opnd(2,k2);
00551 result = fold_htable->Rehash(tmp);
00552 } else
00553 result = NOHASH;
00554 }
00555 } else {
00556 result = NOHASH;
00557 }
00558 return result;
00559 }
00560
00561 #ifdef KEY
00562 static CODEREP *CR_CreateIntconst(OPCODE opc, INT64 val);
00563
00564
00565
00566
00567
00568 CODEREP *
00569 FOLD::CR_Simplify_Iload(CODEREP *cr)
00570 {
00571 if (cr->Ilod_base()->Kind() != CK_LDA)
00572 return NOHASH;
00573 if (MTYPE_byte_size(cr->Dsctyp()) != 1)
00574 return NOHASH;
00575 CODEREP *x = cr->Ilod_base();
00576 ST *s = CR_st(x);
00577 if (ST_class(s) == CLASS_CONST && TCON_ty(ST_tcon_val(s)) == MTYPE_STR) {
00578 TCON c = ST_tcon_val(s);
00579 char *p = Index_to_char_array(TCON_str_idx(c));
00580 p += x->Offset() + cr->Offset();
00581 return CR_CreateIntconst(OPCODE_make_op(OPR_INTCONST, cr->Dtyp(), MTYPE_V),
00582 *p);
00583 }
00584 return NOHASH;
00585 }
00586
00587
00588
00589 static
00590 CODEREP *Combine_bits_any_nzero_test(CODEREP *cr)
00591 {
00592 if (cr->Kind() != CK_OP)
00593 return NOHASH;
00594 if (cr->Opr() != OPR_CIOR && cr->Opr() != OPR_LIOR)
00595 return NOHASH;
00596 CODEREP *l = cr->Opnd(0);
00597 if (l->Kind() == CK_OP && l->Opr() == OPR_NE) {
00598 if (l->Opnd(1)->Kind() == CK_CONST && l->Opnd(1)->Const_val() == 0)
00599 l = l->Opnd(0);
00600 else if (l->Opnd(0)->Kind() == CK_CONST && l->Opnd(0)->Const_val() == 0)
00601 l = l->Opnd(1);
00602 else return NOHASH;
00603 }
00604 CODEREP *r = cr->Opnd(1);
00605 if (r->Kind() == CK_OP && r->Opr() == OPR_NE) {
00606 if (r->Opnd(1)->Kind() == CK_CONST && r->Opnd(1)->Const_val() == 0)
00607 r = r->Opnd(0);
00608 else if (r->Opnd(0)->Kind() == CK_CONST && r->Opnd(0)->Const_val() == 0)
00609 r = r->Opnd(1);
00610 else return NOHASH;
00611 }
00612 CODEREP *lvar, *rvar;
00613 INT64 lbitmask, rbitmask;
00614 if (l->Kind() == CK_OP && l->Opr() == OPR_BAND) {
00615 if (l->Opnd(1)->Kind() == CK_CONST) {
00616 lbitmask = l->Opnd(1)->Const_val();
00617 lvar = l->Opnd(0);
00618 }
00619 else if (l->Opnd(0)->Kind() == CK_CONST) {
00620 lbitmask = l->Opnd(0)->Const_val();
00621 lvar = l->Opnd(1);
00622 }
00623 else return NOHASH;
00624 }
00625 else {
00626 lvar = l;
00627 lbitmask = -1;
00628 }
00629 if (r->Kind() == CK_OP && r->Opr() == OPR_BAND) {
00630 if (r->Opnd(1)->Kind() == CK_CONST) {
00631 rbitmask = r->Opnd(1)->Const_val();
00632 rvar = r->Opnd(0);
00633 }
00634 else if (r->Opnd(0)->Kind() == CK_CONST) {
00635 rbitmask = r->Opnd(0)->Const_val();
00636 rvar = r->Opnd(1);
00637 }
00638 else return NOHASH;
00639 }
00640 else {
00641 rvar = r;
00642 rbitmask = -1;
00643 }
00644 if (lvar != rvar)
00645 return NOHASH;
00646 if (lvar->Kind() != CK_VAR && lvar->Kind() != CK_IVAR)
00647 return NOHASH;
00648
00649 CODEREP *newcr;
00650 INT nbits = MTYPE_bit_size(lvar->Dsctyp());
00651 INT64 maxbitmask;
00652 if (nbits >= 64)
00653 maxbitmask = UINT64_MAX;
00654 else maxbitmask = ((UINT64)1 << nbits) - 1;
00655 INT64 newbitmask = (lbitmask | rbitmask) & maxbitmask;
00656 if (newbitmask == maxbitmask)
00657 newcr = lvar;
00658 else newcr = CR_Create(OPCODE_make_op(OPR_BAND, lvar->Dtyp(), MTYPE_V), 2,
00659 lvar,
00660 CR_CreateIntconst(
00661 OPCODE_make_op(OPR_INTCONST, lvar->Dtyp(), MTYPE_V),
00662 newbitmask));
00663 SIMPNODE_DELETE(cr);
00664 return CR_Create(OPCODE_make_op(OPR_NE, MTYPE_I4, lvar->Dtyp()), 2, newcr,
00665 CR_CreateIntconst(
00666 OPCODE_make_op(OPR_INTCONST, lvar->Dtyp(), MTYPE_V),
00667 0));
00668 }
00669
00670
00671
00672 static
00673 CODEREP *Combine_bits_all_zero_test(CODEREP *cr)
00674 {
00675 if (cr->Kind() != CK_OP)
00676 return NOHASH;
00677 if (cr->Opr() != OPR_CAND && cr->Opr() != OPR_LAND)
00678 return NOHASH;
00679 CODEREP *l = cr->Opnd(0);
00680 if (l->Kind() == CK_OP && l->Opr() == OPR_EQ) {
00681 if (l->Opnd(1)->Kind() == CK_CONST && l->Opnd(1)->Const_val() == 0)
00682 l = l->Opnd(0);
00683 else if (l->Opnd(0)->Kind() == CK_CONST && l->Opnd(0)->Const_val() == 0)
00684 l = l->Opnd(1);
00685 else return NOHASH;
00686 }
00687 else return NOHASH;
00688 CODEREP *r = cr->Opnd(1);
00689 if (r->Kind() == CK_OP && r->Opr() == OPR_EQ) {
00690 if (r->Opnd(1)->Kind() == CK_CONST && r->Opnd(1)->Const_val() == 0)
00691 r = r->Opnd(0);
00692 else if (r->Opnd(0)->Kind() == CK_CONST && r->Opnd(0)->Const_val() == 0)
00693 r = r->Opnd(1);
00694 else return NOHASH;
00695 }
00696 else return NOHASH;
00697 CODEREP *lvar, *rvar;
00698 INT64 lbitmask, rbitmask;
00699 if (l->Kind() == CK_OP && l->Opr() == OPR_BAND) {
00700 if (l->Opnd(1)->Kind() == CK_CONST) {
00701 lbitmask = l->Opnd(1)->Const_val();
00702 lvar = l->Opnd(0);
00703 }
00704 else if (l->Opnd(0)->Kind() == CK_CONST) {
00705 lbitmask = l->Opnd(0)->Const_val();
00706 lvar = l->Opnd(1);
00707 }
00708 else return NOHASH;
00709 }
00710 else {
00711 lvar = l;
00712 lbitmask = -1;
00713 }
00714 if (r->Kind() == CK_OP && r->Opr() == OPR_BAND) {
00715 if (r->Opnd(1)->Kind() == CK_CONST) {
00716 rbitmask = r->Opnd(1)->Const_val();
00717 rvar = r->Opnd(0);
00718 }
00719 else if (r->Opnd(0)->Kind() == CK_CONST) {
00720 rbitmask = r->Opnd(0)->Const_val();
00721 rvar = r->Opnd(1);
00722 }
00723 else return NOHASH;
00724 }
00725 else {
00726 rvar = r;
00727 rbitmask = -1;
00728 }
00729 if (lvar != rvar)
00730 return NOHASH;
00731 if (lvar->Kind() != CK_VAR && lvar->Kind() != CK_IVAR)
00732 return NOHASH;
00733
00734 CODEREP *newcr;
00735 INT nbits = MTYPE_bit_size(lvar->Dsctyp());
00736 INT64 maxbitmask;
00737 if (nbits >= 64)
00738 maxbitmask = UINT64_MAX;
00739 else maxbitmask = ((UINT64)1 << nbits) - 1;
00740 INT64 newbitmask = (lbitmask | rbitmask) & maxbitmask;
00741 if (newbitmask == maxbitmask)
00742 newcr = lvar;
00743 else newcr = CR_Create(OPCODE_make_op(OPR_BAND, lvar->Dtyp(), MTYPE_V), 2,
00744 lvar,
00745 CR_CreateIntconst(
00746 OPCODE_make_op(OPR_INTCONST, lvar->Dtyp(), MTYPE_V),
00747 newbitmask));
00748 SIMPNODE_DELETE(cr);
00749 return CR_Create(OPCODE_make_op(OPR_EQ, MTYPE_I4, lvar->Dtyp()), 2, newcr,
00750 CR_CreateIntconst(
00751 OPCODE_make_op(OPR_INTCONST, lvar->Dtyp(), MTYPE_V),
00752 0));
00753 }
00754 #endif
00755
00756 BOOL
00757 FOLD::check_convert(CODEREP *cr, CODEREP **k, INT kid)
00758 {
00759 if ((*k)->Kind() == CK_OP) {
00760 OPERATOR opr = OPCODE_operator(SIMPNODE_opcode(*k));
00761 if (opr == OPR_CVTL || opr == OPR_CVT) {
00762 BOOL found = FALSE;
00763 *k = CR_Simplify_Expr(*k);
00764 if (*k == NULL)
00765 *k = cr->Opnd(kid);
00766 else if (*k != cr->Opnd(kid))
00767 found = TRUE;
00768 cr->Set_opnd(kid, *k);
00769 return found;
00770 }
00771 }
00772 return FALSE;
00773 }
00774
00775 static CODEREP *
00776 CR_SimpCreateExp1(OPCODE opc, CODEREP *k0)
00777 {
00778 CODEREP *cr;
00779 cr = SIMPNODE_SimplifyExp1(opc, k0);
00780 if (cr == NULL)
00781 cr = CR_Create(opc,1,k0);
00782 return cr;
00783 }
00784
00785 static CODEREP *
00786 CR_SimpCreateExp2(OPCODE opc, CODEREP *k0, CODEREP *k1)
00787 {
00788 CODEREP *cr;
00789 cr = SIMPNODE_SimplifyExp2(opc, k0, k1);
00790 if (cr == NULL)
00791 cr = CR_Create(opc,2,k0,k1);
00792 return cr;
00793 }
00794
00795 static CODEREP *
00796 CR_SimpCreateExp3(OPCODE opc, CODEREP *k0, CODEREP *k1, CODEREP *k2)
00797 {
00798 CODEREP *cr;
00799 cr = SIMPNODE_SimplifyExp3(opc, k0, k1, k2);
00800 if (cr == NULL)
00801 cr = CR_Create(opc,3,k0,k1,k2);
00802 return cr;
00803 }
00804
00805 static CODEREP *
00806 CR_SimpCreateCvtl(OPCODE op, INT16 bits, CODEREP *k0)
00807 {
00808 CODEREP *cr = Alloc_stack_cr(0);
00809 CODEREP *retv = NULL;
00810 const OPERATOR oper = OPCODE_operator(op);
00811 if (fold_trace)
00812 fprintf(TFile,"CR_CreateCvtl, %s, cvtl_bits=%d\n",OPCODE_name(op),bits);
00813 cr->Init_op(op,1);
00814 cr->Set_opnd(0,k0);
00815 cr->Set_offset((mINT32) bits);
00816 retv = fold_htable->Hash_Op(cr);
00817
00818 Is_True(retv,("CR_CreateCvtl, needs work"));
00819 return retv;
00820 }
00821
00822 static CODEREP *
00823 CR_SimpCreateExtract(OPCODE op, INT16 boffset, INT16 bsize, CODEREP *k0)
00824 {
00825 CODEREP *cr = Alloc_stack_cr(0);
00826 CODEREP *retv = NULL;
00827 const OPERATOR oper = OPCODE_operator(op);
00828 if (fold_trace)
00829 fprintf(TFile,"CR_CreateExtract, %s, boffset=%d, bsize=%d\n",OPCODE_name(op),
00830 boffset,bsize);
00831 cr->Init_op(op,1);
00832 cr->Set_opnd(0,k0);
00833 cr->Set_op_bit_offset(boffset);
00834 cr->Set_op_bit_size(bsize);
00835 retv = fold_htable->Hash_Op(cr);
00836
00837 return retv;
00838 }
00839
00840 static CODEREP *
00841 CR_SimpCreateDeposit(OPCODE op, INT16 boffset, INT16 bsize, CODEREP *k0, CODEREP *k1)
00842 {
00843 CODEREP *cr = Alloc_stack_cr(0);
00844 CODEREP *retv = NULL;
00845 const OPERATOR oper = OPCODE_operator(op);
00846 if (fold_trace)
00847 fprintf(TFile,"CR_CreateDeposit, %s, boffset=%d, bsize=%d\n",OPCODE_name(op),
00848 boffset,bsize);
00849 cr->Init_op(op,2);
00850 cr->Set_opnd(0,k0);
00851 cr->Set_opnd(1,k1);
00852 cr->Set_op_bit_offset(boffset);
00853 cr->Set_op_bit_size(bsize);
00854 retv = fold_htable->Hash_Op(cr);
00855
00856 return retv;
00857 }
00858
00859 static CODEREP *
00860 CR_CreateIntconst(OPCODE opc, INT64 val)
00861 {
00862 CODEREP *cr = Alloc_stack_cr(0);
00863 if (opc == OPC_U4INTCONST || opc == OPC_I4INTCONST) {
00864
00865 UINT32 uval = val;
00866 INT32 sval = uval;
00867 val = (INT64) sval;
00868 }
00869 cr->Init_const(OPCODE_rtype(opc),val);
00870 return fold_htable->Hash_Const(cr);
00871 }
00872
00873 static CODEREP *
00874 CR_CreateFPconst(TCON tc)
00875 {
00876 CODEREP *cr = Alloc_stack_cr(0);
00877 ST *st = New_Const_Sym(Enter_tcon(tc),Be_Type_Tbl(TCON_ty(tc)));
00878 cr->Init_rconst(TCON_ty(tc),st);
00879 return fold_htable->Hash_Rconst(cr);
00880 }
00881
00882 #ifdef TARG_X8664
00883 static CODEREP *
00884 CR_CreateSIMDconst(TCON tc)
00885 {
00886 CODEREP *cr = Alloc_stack_cr(0);
00887 ST *st = New_Const_Sym(Enter_tcon(tc),Be_Type_Tbl(TCON_ty(tc)));
00888 cr->Init_rconst(TCON_ty(tc),st);
00889 return fold_htable->Hash_Rconst(cr);
00890 }
00891 #endif
00892
00893
00894 static OPCODE
00895 CR_opcode(CODEREP *cr)
00896 {
00897 switch (cr->Kind()) {
00898 case CK_OP:
00899 case CK_IVAR:
00900 return cr->Op();
00901
00902 case CK_LDA:
00903
00904 return cr->Is_flag_set(CF_LDA_LABEL) ?
00905 OPCODE_make_op(OPR_LDA_LABEL, cr->Dtyp(), MTYPE_V) :
00906 OPCODE_make_op(OPR_LDA, cr->Dtyp(), MTYPE_V);
00907 case CK_CONST:
00908
00909 return OPCODE_make_op(OPR_INTCONST, cr->Dtyp(), MTYPE_V);
00910 case CK_RCONST:
00911
00912 return OPCODE_make_op(OPR_CONST, cr->Dtyp(), MTYPE_V);
00913 case CK_VAR:
00914 #ifdef TARG_SL
00915 if ( cr->Dtyp() == MTYPE_I2 && cr->Dsctyp() == MTYPE_I2) {
00916 return OPCODE_make_op(cr->Bit_field_valid() ? OPR_LDBITS : OPR_LDID,
00917 MTYPE_I4, cr->Dsctyp());
00918 } else
00919 #endif
00920 return OPCODE_make_op(cr->Bit_field_valid() ? OPR_LDBITS : OPR_LDID,
00921 cr->Dtyp(), cr->Dsctyp());
00922 default:
00923 FmtAssert(FALSE,("CRSIMP, CR_opcode, unknown kind, 0x%x",cr->Kind()));
00924 return OPCODE_UNKNOWN;
00925 }
00926 }
00927
00928
00929 static OPERATOR
00930 CR_operator(CODEREP *cr)
00931 {
00932 switch (cr->Kind()) {
00933 case CK_OP:
00934 case CK_IVAR:
00935 return cr->Opr();
00936 case CK_LDA:
00937 return cr->Is_flag_set(CF_LDA_LABEL) ? OPR_LDA_LABEL : OPR_LDA;
00938 case CK_CONST:
00939 return OPR_INTCONST;
00940 case CK_RCONST:
00941 return OPR_CONST;
00942 case CK_VAR:
00943 return cr->Bit_field_valid() ? OPR_LDBITS : OPR_LDID;
00944 default:
00945 FmtAssert(FALSE,("CRSIMP, CR_operator, unknown kind, 0x%x",cr->Kind()));
00946 return OPERATOR_UNKNOWN;
00947 }
00948 }
00949
00950 static TY_IDX
00951 CR_ty(CODEREP *cr)
00952 {
00953 switch (cr->Kind()) {
00954 case CK_VAR:
00955 return cr->Lod_ty();
00956 case CK_LDA:
00957 return cr->Lda_ty();
00958 case CK_IVAR:
00959 return cr->Ilod_ty();
00960 case CK_OP:
00961 return MTYPE_To_TY(cr->Dsctyp());
00962 default:
00963 return TY_IDX_ZERO;
00964 }
00965 }
00966
00967 static ST *
00968 CR_st(CODEREP *cr)
00969 {
00970 switch (cr->Kind()) {
00971 case CK_VAR:
00972 return fold_htable->Sym()->St(cr->Aux_id());
00973 case CK_LDA:
00974 return cr->Lda_base_st();
00975 case CK_RCONST:
00976 return cr->Const_id();
00977 case CK_OP:
00978 #ifdef KEY
00979 if (cr->Opr() == OPR_PURE_CALL_OP)
00980 return &St_Table[cr->Call_op_aux_id()];
00981 #endif
00982 case CK_CONST:
00983 case CK_IVAR:
00984 default:
00985 FmtAssert(FALSE,("CRSIMP, CR_st, no symbol table entry for kind 0x%x",
00986 cr->Kind()));
00987 return NULL;
00988 }
00989 }
00990
00991
00992
00993 static void CR_set_kid0(CODEREP *cr, CODEREP *k0)
00994 {
00995 switch (cr->Kind()) {
00996 case CK_OP:
00997 cr->Set_opnd(0,k0);
00998 break;
00999 case CK_IVAR:
01000 if (cr->Ilod_base())
01001 cr->Set_ilod_base(k0);
01002 if (cr->Istr_base())
01003 cr->Set_istr_base(k0);
01004
01005 break;
01006 default:
01007 FmtAssert(0,("FOLD::CR_set_kid0, unknown kind"));
01008 break;
01009 }
01010 }
01011
01012
01013
01014 static CODEREP *CR_kid0(CODEREP *cr)
01015 {
01016 switch (cr->Kind()) {
01017 case CK_OP:
01018 return cr->Opnd(0);
01019 case CK_IVAR:
01020 return (cr->Ilod_base() != NULL) ? cr->Ilod_base() : cr->Istr_base();
01021 default:
01022 return NULL;
01023 }
01024 }
01025
01026
01027
01028 static CODEREP *CR_kid(CODEREP *cr, INT i)
01029 {
01030 switch (cr->Kind()) {
01031 case CK_OP:
01032 return cr->Opnd(i);
01033 case CK_IVAR:
01034 FmtAssert(i == 0, ("CR_kid, only kid0 defined for indirect reference"));
01035 return (cr->Ilod_base() != NULL) ? cr->Ilod_base() : cr->Istr_base();
01036 default:
01037 return NULL;
01038 }
01039 }
01040
01041
01042 static INT32 CR_kid_count(CODEREP *cr)
01043 {
01044 switch (cr->Kind()) {
01045 case CK_OP:
01046 return cr->Kid_count();
01047 case CK_IVAR:
01048 return (cr->Ilod_base() != NULL || cr->Istr_base() != NULL) ? 1 : 0;
01049 default:
01050 return 0;
01051 }
01052 }
01053
01054
01055
01056 INT32 CR_Compare_Symbols(CODEREP *t1, CODEREP *t2)
01057 {
01058
01059
01060
01061 if (t1->Kind() == CK_VAR && t2->Kind() == CK_VAR && t1 == t2)
01062 return 0;
01063
01064 ST *s1 = SIMPNODE_st(t1);
01065 ST *s2 = SIMPNODE_st(t2);
01066 if (s1 != s2) {
01067 ST_IDX idx1 = ST_st_idx(s1);
01068 ST_IDX idx2 = ST_st_idx(s2);
01069 UINT s1id = ST_IDX_level(idx1);
01070 UINT s2id = ST_IDX_level(idx2);
01071 if (s1id < s2id) return -1;
01072 if (s1id > s2id) return 1;
01073 ST_IDX s1index = ST_IDX_index(idx1);
01074 ST_IDX s2index = ST_IDX_index(idx2);
01075 if (s1index < s2index) return -1;
01076 if (s1index > s2index) return 1;
01077 }
01078
01079
01080
01081
01082 if (t1->Kind() == CK_VAR && t2->Kind() == CK_VAR) {
01083 if (t1->Coderep_id() < t2->Coderep_id())
01084 return -1;
01085 else if (t1->Coderep_id() > t2->Coderep_id())
01086 return 1;
01087 }
01088 return 0;
01089 }
01090
01091
01092
01093 INT32 CR_Compare_Trees(CODEREP *t1, CODEREP *t2)
01094 {
01095
01096 if (t1->Non_leaf() || t2->Non_leaf()) return 0;
01097 if (t1->Kind() == t2->Kind() &&
01098 t1->Kind() == CK_VAR) {
01099 if (SIMPNODE_load_offset(t1) < SIMPNODE_load_offset(t2)) return(-1);
01100 if (SIMPNODE_load_offset(t1) > SIMPNODE_load_offset(t2)) return(1);
01101 return SIMPNODE_Compare_Symbols(t1,t2);
01102 }
01103 else if (inCODEKIND(t1->Kind(), CK_VAR | CK_LDA | CK_RCONST) &&
01104 inCODEKIND(t2->Kind(), CK_VAR | CK_LDA | CK_RCONST)) {
01105 return SIMPNODE_Compare_Symbols(t1,t2);
01106 }
01107 return 0;
01108 }
01109
01110
01111
01112 #include "wn_simp_code.h"
01113
01114
01115
01116
01117
01118 static void CR_Simplify_Initialize( void )
01119 {
01120 trace_rules = trace_trees = fold_trace;
01121 SIMPNODE_simp_initialized = TRUE;
01122 }