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 #ifdef USE_PCH
00062 #include "opt_pch.h"
00063 #endif // USE_PCH
00064 #pragma hdrstop
00065
00066
00067 #define __STDC_LIMIT_MACROS
00068 #include <stdint.h>
00069 #include "defs.h"
00070 #include "erglob.h"
00071 #include "opcode.h"
00072 #include "errors.h"
00073 #include "mtypes.h"
00074 #include "cxx_memory.h"
00075 #include "wn_util.h"
00076 #include "targ_const.h"
00077 #include "targ_const_private.h"
00078 #include "const.h"
00079
00080 #include "opt_config.h"
00081 #include "opt_wn.h"
00082 #include "opt_util.h"
00083 #include "opt_cfg.h"
00084 #include "opt_htable.h"
00085 #include "opt_vn_expr_taxonomy.h"
00086 #include "opt_vn.h"
00087
00088 #ifdef __STL_USE_NAMESPACES
00089 using std::pair;
00090 #endif
00091
00092 typedef pair<VN_VALNUM,VN_VALNUM> VN_VALNUM_PAIR;
00093
00094
00095 void
00096 VN_VALNUM::print(FILE *fp) const
00097 {
00098 char buf[16];
00099 this->sprint(buf);
00100 fputs(buf, fp);
00101 }
00102
00103
00104 INT32
00105 VN_VALNUM::sprint(char *buf) const
00106 {
00107 INT32 idx = 0;
00108
00109 if (is_bottom())
00110 idx += sprintf(buf, "_|_");
00111 else if (is_top())
00112 idx += sprintf(buf, "T");
00113 else
00114 idx += sprintf(buf, "vn%u", _num);
00115 return idx;
00116 }
00117
00118
00119
00120
00121
00122 inline void
00123 Unimplemented(const char *method)
00124 {
00125 FmtAssert(FALSE, ("Illegal call to method %s", method));
00126 }
00127
00128
00129 inline VN_EXPR *
00130 Create_Folded_Literal(OPCODE opc,
00131 VN_EXPR::CONST_PTR opnd1,
00132 VN_EXPR::CONST_PTR opnd2)
00133 {
00134
00135
00136 BOOL folded = FALSE;
00137 TCON tcon1 = opnd1->get_tcon();
00138 TCON tcon2 = opnd2->get_tcon();
00139 TCON tcon = Targ_WhirlOp(opc, tcon1, tcon2, &folded);
00140 if (folded)
00141 return VN_EXPR::Create_Literal(tcon);
00142 else
00143 return NULL;
00144 }
00145
00146
00147 inline VN_EXPR *
00148 Create_Unary_Opr(OPERATOR opr, const VN_VALNUM &vn, MTYPE mtype)
00149 {
00150 return VN_EXPR::Create_Unary(OPCODE_make_op(opr, mtype, MTYPE_V), vn);
00151 }
00152
00153
00154 inline VN_EXPR *
00155 Create_Binary_Opr(OPERATOR opr,
00156 const VN_VALNUM &vn1,
00157 const VN_VALNUM &vn2,
00158 MTYPE rtype,
00159 MTYPE dtype)
00160 {
00161 return VN_EXPR::Create_Binary(OPCODE_make_op(opr, rtype, dtype), vn1, vn2);
00162 }
00163
00164
00165 static MTYPE
00166 Unify_Rty(OPERATOR opr, MTYPE rty)
00167 {
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 MTYPE new_rty = rty;
00178
00179 if (MTYPE_is_integral(rty))
00180 {
00181 UINT32 bitsize = MTYPE_bit_size(rty);
00182
00183 switch (opr)
00184 {
00185 case OPR_ADD:
00186 case OPR_SUB:
00187 case OPR_MPY:
00188 case OPR_DIV:
00189 case OPR_REM:
00190 case OPR_BAND:
00191 case OPR_BIOR:
00192 case OPR_BNOR:
00193 case OPR_BXOR:
00194 case OPR_SHL:
00195 case OPR_ASHR:
00196 case OPR_LSHR:
00197
00198 case OPR_NEG:
00199 case OPR_BNOT:
00200 case OPR_SELECT:
00201 if (bitsize == 32U)
00202 new_rty = MTYPE_I4;
00203 else if (bitsize == 64U)
00204 new_rty = MTYPE_I8;
00205 break;
00206
00207 default:
00208 break;
00209 }
00210 }
00211
00212 return new_rty;
00213 }
00214
00215
00216 inline BOOL
00217 Is_Literal_Expr(const VN_EXPR *expr)
00218 {
00219 return (expr != NULL && expr->get_kind() == VN_EXPR::LITERAL);
00220 }
00221
00222
00223 inline BOOL
00224 Is_Singular_Expr(const VN_EXPR *expr)
00225 {
00226 return (expr != NULL &&
00227 expr->get_kind() == VN_EXPR::UNARY &&
00228 expr->get_opc() == OPC_VPARM);
00229 }
00230
00231
00232 inline BOOL
00233 Is_Rty_Opr(VN_EXPR::CONST_PTR expr,
00234 VN_EXPR::KIND kind,
00235 OPERATOR opr1,
00236 MTYPE rty)
00237 {
00238 if (expr != NULL && expr->get_kind() == kind)
00239 {
00240 const OPCODE opc = expr->get_opc();
00241 const OPERATOR opr = OPCODE_operator(opc);
00242 const MTYPE opc_rty = Unify_Rty(opr, OPCODE_rtype(opc));
00243 return (opr == opr1 && opc_rty == rty);
00244 }
00245 else
00246 return FALSE;
00247 }
00248
00249
00250 inline BOOL
00251 Is_Rty_Opr2(VN_EXPR::CONST_PTR expr,
00252 VN_EXPR::KIND kind,
00253 OPERATOR opr1,
00254 OPERATOR opr2,
00255 MTYPE rty)
00256 {
00257 if (expr != NULL && expr->get_kind() == kind)
00258 {
00259 const OPCODE opc = expr->get_opc();
00260 const OPERATOR opr = OPCODE_operator(opc);
00261 const MTYPE opc_rty = Unify_Rty(opr, OPCODE_rtype(opc));
00262 return ((opr == opr1 || opr == opr2) && opc_rty == rty);
00263 }
00264 else
00265 return FALSE;
00266 }
00267
00268
00269 static BOOL
00270 All_Bits_Set(INT64 i, INT32 num_bytes)
00271 {
00272 switch (num_bytes)
00273 {
00274 case 1:
00275 return (mUINT8)i == 0xffU;
00276 case 2:
00277 return (mUINT16)i == 0xffffU;
00278 case 4:
00279 return (mUINT32)i == 0xffffffffU;
00280 case 8:
00281 return (mUINT64)i == 0xffffffffffffffffULL;
00282 default:
00283 return FALSE;
00284 }
00285 }
00286
00287
00288 static VN_EXPR::PTR
00289 Create_Scalar_Literal_From_Int(MTYPE mty, INT64 i)
00290 {
00291 VN_EXPR::PTR p;
00292
00293 switch (mty)
00294 {
00295 case MTYPE_B:
00296 case MTYPE_I1:
00297 case MTYPE_I2:
00298 case MTYPE_I4:
00299 case MTYPE_I8:
00300 case MTYPE_U1:
00301 case MTYPE_U2:
00302 case MTYPE_U4:
00303 case MTYPE_U8:
00304 p = VN_EXPR::Create_Literal(Host_To_Targ(mty, i));
00305 break;
00306
00307 case MTYPE_F4:
00308 case MTYPE_F8:
00309 case MTYPE_F10:
00310 case MTYPE_FQ:
00311 p = VN_EXPR::Create_Literal(Host_To_Targ_Float(mty, i));
00312 break;
00313
00314 default:
00315 FmtAssert(FALSE, ("Unexpected mtype in Create_Literal_From_Int()"));
00316 break;
00317 }
00318 return p;
00319 }
00320
00321
00322
00323
00324
00325
00326
00327
00328 MEM_POOL *VN_EXPR::_Mpool = NULL;
00329
00330
00331
00332 FREE_STACK *VN_LITERAL_EXPR::_Free = NULL;
00333 FREE_STACK *VN_UNARY_EXPR::_Free = NULL;
00334 FREE_STACK *VN_BINARY_EXPR::_Free = NULL;
00335 FREE_STACK *VN_TERNARY_EXPR::_Free = NULL;
00336 FREE_STACK *VN_INTR_OP_EXPR::_Free = NULL;
00337 FREE_STACK *VN_PHI_EXPR::_Free = NULL;
00338 FREE_STACK *VN_LDA_ADDR_EXPR::_Free = NULL;
00339 FREE_STACK *VN_ARRAY_ADDR_EXPR::_Free = NULL;
00340 FREE_STACK *VN_MEMLOC_EXPR::_Free = NULL;
00341 #ifdef KEY
00342 FREE_STACK *VN_CALL_OP_EXPR::_Free = NULL;
00343 #endif
00344
00345
00346 void
00347 VN_EXPR::Init_Free_Lists(MEM_POOL *mpool)
00348 {
00349 _Mpool = mpool;
00350 VN_LITERAL_EXPR::Init_Free_List();
00351 VN_UNARY_EXPR::Init_Free_List();
00352 VN_BINARY_EXPR::Init_Free_List();
00353 VN_TERNARY_EXPR::Init_Free_List();
00354 VN_INTR_OP_EXPR::Init_Free_List();
00355 VN_PHI_EXPR::Init_Free_List();
00356 VN_LDA_ADDR_EXPR::Init_Free_List();
00357 VN_ARRAY_ADDR_EXPR::Init_Free_List();
00358 VN_MEMLOC_EXPR::Init_Free_List();
00359 #ifdef KEY
00360 VN_CALL_OP_EXPR::Init_Free_List();
00361 #endif
00362 }
00363
00364
00365 void
00366 VN_EXPR::Reclaim_Free_Lists()
00367 {
00368 if (_Mpool != NULL)
00369 {
00370 VN_LITERAL_EXPR::Reclaim_Free_List();
00371 VN_UNARY_EXPR::Reclaim_Free_List();
00372 VN_BINARY_EXPR::Reclaim_Free_List();
00373 VN_TERNARY_EXPR::Reclaim_Free_List();
00374 VN_INTR_OP_EXPR::Reclaim_Free_List();
00375 VN_PHI_EXPR::Reclaim_Free_List();
00376 VN_LDA_ADDR_EXPR::Reclaim_Free_List();
00377 VN_ARRAY_ADDR_EXPR::Reclaim_Free_List();
00378 VN_MEMLOC_EXPR::Reclaim_Free_List();
00379 #ifdef KEY
00380 VN_CALL_OP_EXPR::Reclaim_Free_List();
00381 #endif
00382 }
00383 }
00384
00385
00386 VN_EXPR::PTR
00387 VN_EXPR::Create_Literal(const TCON &tcon)
00388 {
00389 return VN_LITERAL_EXPR::Create(tcon);
00390 }
00391
00392
00393 VN_EXPR::PTR
00394 VN_EXPR::Create_Unary(OPCODE opc,
00395 const VN_VALNUM &vn1)
00396 {
00397 return VN_UNARY_EXPR::Create(opc, vn1);
00398 }
00399
00400
00401 VN_EXPR::PTR
00402 VN_EXPR::Create_Binary(OPCODE opc,
00403 const VN_VALNUM &vn1,
00404 const VN_VALNUM &vn2)
00405 {
00406 return VN_BINARY_EXPR::Create(opc, vn1, vn2);
00407 }
00408
00409
00410 VN_EXPR::PTR
00411 VN_EXPR::Create_Ternary(OPCODE opc,
00412 const VN_VALNUM &vn1,
00413 const VN_VALNUM &vn2,
00414 const VN_VALNUM &vn3)
00415 {
00416 return VN_TERNARY_EXPR::Create(opc, vn1, vn2, vn3);
00417 }
00418
00419
00420 VN_EXPR::PTR
00421 VN_EXPR::Create_Intr_Op(INTRINSIC intr_opc, UINT32 num_opnds)
00422 {
00423 return VN_INTR_OP_EXPR::Create(intr_opc, num_opnds);
00424 }
00425
00426
00427 VN_EXPR::PTR
00428 VN_EXPR::Create_Phi(UINT32 num_opnds,
00429 IDTYPE block_id,
00430 PHI_TAG phi_tag)
00431 {
00432 return VN_PHI_EXPR::Create(num_opnds, block_id, phi_tag);
00433 }
00434
00435
00436 VN_EXPR::PTR
00437 VN_EXPR::Create_Lda_Addr(INT32 lda_cr_id)
00438 {
00439 return VN_LDA_ADDR_EXPR::Create(lda_cr_id);
00440 }
00441
00442
00443 VN_EXPR::PTR
00444 VN_EXPR::Create_Array_Addr(WN_ESIZE esize, INT32 num_dims)
00445 {
00446 return VN_ARRAY_ADDR_EXPR::Create(esize, num_dims);
00447 }
00448
00449
00450 VN_EXPR::PTR
00451 VN_EXPR::Create_Memloc(MTYPE dsctype,
00452 const VN_VALNUM &bytesize,
00453 const VN_VALNUM &offset,
00454 const VN_VALNUM &base_addr,
00455 const VN_VALNUM &vsym_valnum)
00456 {
00457 return VN_MEMLOC_EXPR::Create(dsctype,
00458 bytesize, offset,base_addr, vsym_valnum);
00459 }
00460
00461
00462 #ifdef KEY
00463 VN_EXPR::PTR
00464 VN_EXPR::Create_Call_Op(ST_IDX aux_id, UINT32 num_opnds)
00465 {
00466 return VN_CALL_OP_EXPR::Create(aux_id, num_opnds);
00467 }
00468 #endif
00469
00470 VN_VALNUM
00471 VN_EXPR::get_opnd(UINT) const
00472 {
00473 Unimplemented("VN_EXPR::get_opnd");
00474 return VN_VALNUM::Bottom();
00475 }
00476
00477 OPCODE
00478 VN_EXPR::get_opc() const
00479 {
00480 Unimplemented("VN_EXPR::get_opc");
00481 return OPCODE_UNKNOWN;
00482 }
00483
00484 INTRINSIC
00485 VN_EXPR::get_intr_opc() const
00486 {
00487 Unimplemented("VN_EXPR::get_intr_opc");
00488 return INTRINSIC_INVALID;
00489 }
00490
00491 VN_EXPR::PHI_TAG
00492 VN_EXPR::get_phi_tag() const
00493 {
00494 Unimplemented("VN_EXPR::get_phi_tag");
00495 return PHI_TAG_UNKNOWN;
00496 }
00497
00498 IDTYPE
00499 VN_EXPR::get_block_id() const
00500 {
00501 Unimplemented("VN_EXPR::get_block_id");
00502 return (IDTYPE) 0;
00503 }
00504
00505 const TCON &
00506 VN_EXPR::get_tcon() const
00507 {
00508 Unimplemented("VN_EXPR::get_tcon");
00509 return Zero_I4_Tcon;
00510 }
00511
00512 void
00513 VN_EXPR::set_opnd(UINT32, VN_VALNUM)
00514 {
00515 Unimplemented("VN_EXPR::set_opnd");
00516 }
00517
00518 void
00519 VN_EXPR::set_opnd_vsym(UINT32, VN_VALNUM)
00520 {
00521 Unimplemented("VN_EXPR::set_opnd");
00522 }
00523
00524 INT32
00525 VN_EXPR::get_lda_cr_id() const
00526 {
00527 Unimplemented("VN_EXPR::get_aux_symbol_id");
00528 return -1;
00529 }
00530
00531 INT32
00532 VN_EXPR::get_num_dims() const
00533 {
00534 Unimplemented("VN_EXPR::get_num_dims");
00535 return -1;
00536 }
00537
00538 WN_ESIZE
00539 VN_EXPR::get_esize() const
00540 {
00541 Unimplemented("VN_EXPR::get_esize");
00542 return -1;
00543 }
00544
00545 MTYPE
00546 VN_EXPR::get_dsctype() const
00547 {
00548 Unimplemented("VN_EXPR::get_dsctype");
00549 return MTYPE_UNKNOWN;
00550 }
00551
00552 VN_VALNUM
00553 VN_EXPR::get_bytesize() const
00554 {
00555 Unimplemented("VN_EXPR::get_bytesize");
00556 return VN_VALNUM::Bottom();
00557 }
00558
00559 VN_VALNUM
00560 VN_EXPR::get_offset() const
00561 {
00562 Unimplemented("VN_EXPR::get_offset");
00563 return VN_VALNUM::Bottom();
00564 }
00565
00566 VN_VALNUM
00567 VN_EXPR::get_base_addr() const
00568 {
00569 Unimplemented("VN_EXPR::get_base_addr");
00570 return VN_VALNUM::Bottom();
00571 }
00572
00573 VN_VALNUM
00574 VN_EXPR::get_vsym(UINT) const
00575 {
00576 Unimplemented("VN_EXPR::get_vsym");
00577 return VN_VALNUM::Bottom();
00578 }
00579
00580 #ifdef KEY
00581 ST_IDX
00582 VN_EXPR::get_aux_id() const
00583 {
00584 Unimplemented("VN_EXPR::get_aux_id");
00585 return 0;
00586 }
00587 #endif
00588
00589
00590
00591
00592
00593 BOOL
00594 VN_LITERAL_EXPR::is_equal_to(CONST_PTR expr) const
00595 {
00596
00597
00598 BOOL truth = FALSE;
00599
00600 if (Is_Literal_Expr(expr))
00601 {
00602 const MTYPE this_mty = TCON_ty(_tcon);
00603 TCON other_tcon = expr->get_tcon();
00604 const MTYPE other_mty = TCON_ty(other_tcon);
00605
00606 #ifdef TARG_X8664
00607 if (MTYPE_is_vector(this_mty) || MTYPE_is_vector(other_mty))
00608 return FALSE;
00609 #endif
00610 if (MTYPE_is_integral(this_mty) && MTYPE_is_integral(other_mty))
00611 {
00612
00613
00614
00615
00616
00617
00618 const INT64 int1 = Targ_To_Host(_tcon);
00619 const INT64 int2 = Targ_To_Host(other_tcon);
00620 truth = (int1 == int2 &&
00621 ((int1 > 0LL && int2 > 0LL) ||
00622 MTYPE_is_signed(this_mty) == MTYPE_is_signed(other_mty)));
00623 }
00624 else if (this_mty == other_mty)
00625 {
00626 if (this_mty == MTYPE_STRING)
00627 truth =
00628 (Targ_String_Length(_tcon) == Targ_String_Length(other_tcon) &&
00629 strncmp(Targ_String_Address(_tcon),
00630 Targ_String_Address(other_tcon),
00631 Targ_String_Length(_tcon)));
00632 #ifdef KEY
00633
00634
00635
00636 else if (this_mty == MTYPE_F8 &&
00637 TCON_R8(other_tcon) == 0 && TCON_R8(_tcon) == 0)
00638 truth = TCON_v1(other_tcon) == TCON_v1(_tcon);
00639 else if (this_mty == MTYPE_F4 &&
00640 TCON_R4(other_tcon) == 0 && TCON_R4(_tcon) == 0)
00641 truth = TCON_word0(other_tcon) == TCON_word0(_tcon);
00642 #endif
00643 else
00644 {
00645 BOOL folded;
00646 other_tcon =
00647 Targ_WhirlOp(OPCODE_make_op(OPR_EQ,
00648 WHIRL_Mtype_B_On ? MTYPE_B : MTYPE_I4, this_mty),
00649 other_tcon, _tcon, &folded);
00650 truth = folded && Targ_To_Host(other_tcon) != 0;
00651 }
00652 }
00653 }
00654 return truth;
00655 }
00656
00657
00658
00659
00660
00661 VN_UNARY_EXPR *
00662 VN_UNARY_EXPR::Create(OPCODE opc, const VN_VALNUM &vn)
00663 {
00664 Is_True(OPCODE_nkids(opc) == 1,
00665 ("Unexpected opcode in call to VN_UNARY_EXPR::Create()"));
00666
00667 VN_UNARY_EXPR *expr = (VN_UNARY_EXPR *)_Free->pop();
00668 if (expr == NULL)
00669 expr = CXX_NEW(VN_UNARY_EXPR(opc, vn), _Mpool);
00670 else
00671 {
00672 expr->_opc = opc;
00673 expr->_vn = vn;
00674 }
00675 return expr;
00676 }
00677
00678
00679 VN_EXPR::PTR
00680 VN_UNARY_EXPR::simplify(VN *v)
00681 {
00682 PTR simplified = this;
00683 PTR opnd = v->valnum_expr(_vn);
00684 const OPERATOR opr = OPCODE_operator(_opc);
00685 const MTYPE rty = Unify_Rty(opr, OPCODE_rtype(_opc));
00686
00687 Is_True(opr != OPR_PARM,
00688 ("Unexpected opcode in call to VN_UNARY_EXPR::simplify()"));
00689
00690
00691
00692
00693
00694 if (rty != OPCODE_rtype(_opc))
00695 _opc = OPCODE_make_op(opr, rty, OPCODE_desc(_opc));
00696
00697 if (has_bottom_opnd() || has_top_opnd())
00698 {
00699 simplified = Create_Unary(OPC_VPARM, VN_VALNUM::Bottom());
00700 }
00701 else if (Is_Literal_Expr(opnd))
00702 {
00703
00704 if (
00705 #ifndef TARG_X8664
00706 !Split_64_Bit_Int_Ops ||
00707 #endif
00708 opr != OPR_CVT ||
00709 MTYPE_bit_size(OPCODE_rtype(_opc)) != 64 ||
00710 MTYPE_bit_size(OPCODE_desc(_opc)) != 32) {
00711
00712
00713 PTR s = Create_Folded_Literal(_opc, opnd, opnd);
00714 if (s != NULL)
00715 simplified = s;
00716 }
00717 }
00718 else if (opr == OPR_NEG &&
00719 MTYPE_is_integral(rty) &&
00720 Is_Rty_Opr(opnd, BINARY, OPR_SUB, rty))
00721 {
00722
00723
00724 simplified = Create_Binary(opnd->get_opc(),
00725 opnd->get_opnd(1),
00726 opnd->get_opnd(0));
00727 }
00728
00729 if (simplified != this)
00730 free();
00731
00732 return simplified;
00733 }
00734
00735
00736
00737
00738
00739 void
00740 VN_BINARY_EXPR::_canonicalize()
00741 {
00742
00743
00744
00745
00746 OPCODE opc1 = OPCODE_commutative_op(_opc);
00747 if (opc1 != OPCODE_UNKNOWN && _vn[0] > _vn[1])
00748 {
00749 Switch_Vn_Opnd(_vn[0], _vn[1]);
00750 _opc = opc1;
00751 }
00752 else
00753 {
00754 const OPERATOR opr = OPCODE_operator(_opc);
00755 if (opr == OPR_GE)
00756 {
00757 Switch_Vn_Opnd(_vn[0], _vn[1]);
00758 _opc = OPCODE_make_op(OPR_LE, OPCODE_rtype(_opc), OPCODE_desc(_opc));
00759 }
00760 else if (opr == OPR_GT)
00761 {
00762 Switch_Vn_Opnd(_vn[0], _vn[1]);
00763 _opc = OPCODE_make_op(OPR_LT, OPCODE_rtype(_opc), OPCODE_desc(_opc));
00764 }
00765 }
00766 }
00767
00768
00769 VN_EXPR::PTR
00770 VN_BINARY_EXPR::_fold_2literals(OPERATOR opr1,
00771 CONST_PTR literal1,
00772 OPERATOR opr2,
00773 CONST_PTR literal2)
00774 {
00775 const MTYPE rty = OPCODE_rtype(_opc);
00776 PTR result = NULL;
00777
00778 Is_True((opr1 == OPR_ADD || opr1 == OPR_SUB) &&
00779 (opr2 == OPR_ADD || opr2 == OPR_SUB),
00780 ("Unexpected operator in VN_BINARY_EXPR::_fold_2literals"));
00781 Is_True(literal1->get_kind() == LITERAL &&
00782 literal2->get_kind() == LITERAL &&
00783 MTYPE_is_integral(rty),
00784 ("Expected int literal in VN_BINARY_EXPR::_fold_2literals"));
00785
00786 if (opr1 == OPR_SUB && opr2 == OPR_SUB)
00787 {
00788
00789
00790 PTR tmp = Create_Folded_Literal(OPCODE_make_op(OPR_NEG, rty, MTYPE_V),
00791 literal1, literal1);
00792
00793 if (tmp != NULL)
00794 {
00795 result = Create_Folded_Literal(OPCODE_make_op(OPR_SUB, rty, MTYPE_V),
00796 tmp, literal2);
00797 tmp->free();
00798 }
00799 }
00800 else
00801 {
00802
00803
00804
00805
00806 if (opr1 == OPR_SUB)
00807 result = Create_Folded_Literal(OPCODE_make_op(OPR_SUB, rty, MTYPE_V),
00808 literal2, literal1);
00809 else
00810 result = Create_Folded_Literal(OPCODE_make_op(opr2, rty, MTYPE_V),
00811 literal1, literal2);
00812 }
00813 return result;
00814 }
00815
00816
00817 VN_EXPR::PTR
00818 VN_BINARY_EXPR::_simplify_2literals(OPERATOR opr1,
00819 CONST_PTR literal1,
00820 OPERATOR opr2,
00821 CONST_PTR literal2,
00822 OPERATOR opr3,
00823 VN_VALNUM vn3,
00824 VN *v)
00825 {
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838 const MTYPE rty = OPCODE_rtype(_opc);
00839 PTR simplified = this;
00840
00841 Is_True((opr1 == OPR_ADD || opr1 == OPR_SUB) &&
00842 (opr2 == OPR_ADD || opr2 == OPR_SUB) &&
00843 (opr3 == OPR_ADD || opr3 == OPR_SUB),
00844 ("Unexpected operator in VN_BINARY_EXPR::_simplify_2literals"));
00845 Is_True(literal1->get_kind() == LITERAL &&
00846 literal2->get_kind() == LITERAL &&
00847 MTYPE_is_integral(rty),
00848 ("Expected int literal in VN_BINARY_EXPR::_simplify_2literals"));
00849
00850 PTR literal = _fold_2literals(opr1, literal1, opr2, literal2);
00851
00852
00853
00854 if (literal != NULL)
00855 {
00856 if (Targ_Is_Zero(literal->get_tcon()))
00857 {
00858 if (opr3 == OPR_ADD)
00859 simplified = Create_Unary(OPC_VPARM, vn3);
00860 else
00861 simplified = Create_Unary_Opr(OPR_NEG, vn3, rty);
00862 }
00863 else
00864 {
00865 VN_VALNUM literal_vn = v->valnum_integer(literal->get_tcon());
00866
00867 simplified = Create_Binary_Opr(opr3, literal_vn, vn3, rty, MTYPE_V);
00868 }
00869 literal->free();
00870 }
00871
00872 return simplified;
00873 }
00874
00875
00876 VN_EXPR::PTR
00877 VN_BINARY_EXPR::_simplify_3adds(OPERATOR opr0,
00878 VN_VALNUM vn0,
00879 OPERATOR opr1,
00880 VN_VALNUM vn1,
00881 OPERATOR opr2,
00882 VN_VALNUM vn2,
00883 VN *v)
00884 {
00885
00886
00887
00888 PTR tmp = NULL;
00889 PTR simplified = this;
00890 CONST_PTR opnd0 = v->valnum_expr(vn0);
00891 CONST_PTR opnd1 = v->valnum_expr(vn1);
00892 CONST_PTR opnd2 = v->valnum_expr(vn2);
00893
00894 Is_True((opr0 == OPR_ADD || opr0 == OPR_SUB) &&
00895 (opr1 == OPR_ADD || opr1 == OPR_SUB) &&
00896 (opr2 == OPR_ADD || opr2 == OPR_SUB),
00897 ("Unexpected operator in VN_BINARY_EXPR::_simplify_3adds"));
00898
00899
00900
00901 {
00902 OPERATOR opr;
00903 VN_VALNUM vn;
00904
00905
00906
00907 if (opr0 != opr1 && vn0 == vn1)
00908 {
00909 simplified = NULL; opr = opr2; vn = vn2;
00910 }
00911 else if (opr0 != opr2 && vn0 == vn2)
00912 {
00913 simplified = NULL; opr = opr1; vn = vn1;
00914 }
00915 else if (opr1 != opr2 && vn1 == vn2)
00916 {
00917 simplified = NULL; opr = opr0; vn = vn0;
00918 }
00919
00920
00921
00922 if (simplified == NULL)
00923 {
00924 if (opr == OPR_ADD)
00925 simplified = Create_Unary(OPC_VPARM, vn);
00926 else
00927 simplified = Create_Unary_Opr(OPR_NEG, vn, OPCODE_rtype(_opc));
00928 }
00929 }
00930
00931
00932
00933 if (simplified == this)
00934 {
00935 if (Is_Literal_Expr(opnd0))
00936 {
00937 if (Is_Literal_Expr(opnd1))
00938 {
00939
00940
00941 simplified =
00942 _simplify_2literals(opr0, opnd0, opr1, opnd1, opr2, vn2, v);
00943 }
00944 else if (Is_Literal_Expr(opnd2))
00945 {
00946
00947
00948 simplified =
00949 _simplify_2literals(opr0, opnd0, opr2, opnd2, opr1, vn1, v);
00950 }
00951 }
00952 else if (Is_Literal_Expr(opnd1) && Is_Literal_Expr(opnd2))
00953 {
00954
00955
00956 simplified =
00957 _simplify_2literals(opr1, opnd1, opr2, opnd2, opr0, vn0, v);
00958 }
00959 }
00960
00961 return simplified;
00962 }
00963
00964
00965 VN_EXPR::PTR
00966 VN_BINARY_EXPR::_simplify_4adds(OPERATOR opr0,
00967 VN_VALNUM vn0,
00968 OPERATOR opr1,
00969 VN_VALNUM vn1,
00970 OPERATOR opr2,
00971 VN_VALNUM vn2,
00972 OPERATOR opr3,
00973 VN_VALNUM vn3,
00974 VN *v)
00975 {
00976
00977
00978
00979
00980
00981
00982
00983 PTR simplified = this;
00984 OPERATOR opr[4];
00985 VN_VALNUM opnd[4];
00986 CONST_PTR opnd_expr[4];
00987
00988 Is_True((opr0 == OPR_ADD || opr0 == OPR_SUB) &&
00989 (opr1 == OPR_ADD || opr1 == OPR_SUB) &&
00990 (opr2 == OPR_ADD || opr2 == OPR_SUB) &&
00991 (opr3 == OPR_ADD || opr3 == OPR_SUB),
00992 ("Unexpected operator in VN_BINARY_EXPR::_simplify_4adds"));
00993
00994
00995
00996 opr[0] = opr0;
00997 opr[1] = opr1;
00998 opr[2] = opr2;
00999 opr[3] = opr3;
01000 opnd[0] = vn0;
01001 opnd[1] = vn1;
01002 opnd[2] = vn2;
01003 opnd[3] = vn3;
01004 opnd_expr[0] = v->valnum_expr(vn0);
01005 opnd_expr[1] = v->valnum_expr(vn1);
01006 opnd_expr[2] = v->valnum_expr(vn2);
01007 opnd_expr[3] = v->valnum_expr(vn3);
01008
01009
01010
01011 PTR literal = NULL;
01012 INT32 first_literal_idx = -1;
01013 INT32 non_literal_idx = -1;
01014 INT32 num_non_literals = 0;
01015
01016 for (INT32 i = 0; i < 4; i++)
01017 {
01018 if (literal == NULL && Is_Literal_Expr(opnd_expr[i]))
01019 {
01020 if (first_literal_idx == -1)
01021 first_literal_idx = i;
01022 else
01023 {
01024 literal = _fold_2literals(opr[first_literal_idx],
01025 opnd_expr[first_literal_idx],
01026 opr[i],
01027 opnd_expr[i]);
01028 }
01029 }
01030 else
01031 {
01032 if (non_literal_idx == -1)
01033 {
01034 non_literal_idx = i;
01035 ++num_non_literals;
01036 }
01037 else if (opnd[non_literal_idx] == opnd[i] &&
01038 opr[non_literal_idx] != opr[i])
01039 {
01040 --num_non_literals;
01041 non_literal_idx = -1;
01042 }
01043 else
01044 {
01045 ++num_non_literals;
01046 }
01047 }
01048 }
01049
01050 if (num_non_literals == 0 && literal != NULL)
01051 simplified = literal;
01052 else if (literal != NULL)
01053 literal->free();
01054
01055 return simplified;
01056 }
01057
01058
01059 VN_EXPR::PTR
01060 VN_BINARY_EXPR::_simplify_add(CONST_PTR opnd1, CONST_PTR opnd2, VN *v)
01061 {
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072 PTR simplified = this;
01073 const MTYPE rty = OPCODE_rtype(_opc);
01074
01075 Is_True(OPCODE_operator(_opc) == OPR_ADD,
01076 ("Illegal opcode for VN_BINARY_EXPR::_simplify_add"));
01077
01078 if (Is_Rty_Opr(opnd1, UNARY, OPR_NEG, rty))
01079 {
01080
01081
01082 simplified = Create_Binary_Opr(OPR_SUB,
01083 get_opnd(1), opnd1->get_opnd(),
01084 rty, MTYPE_V);
01085 }
01086 else if (Is_Rty_Opr(opnd2, UNARY, OPR_NEG, rty))
01087 {
01088
01089
01090 simplified = Create_Binary_Opr(OPR_SUB,
01091 get_opnd(0), opnd2->get_opnd(),
01092 rty, MTYPE_V);
01093 }
01094 else
01095 {
01096
01097
01098
01099
01100 if (Is_Rty_Opr2(opnd1, BINARY, OPR_SUB, OPR_ADD, rty) &&
01101 Is_Rty_Opr2(opnd2, BINARY, OPR_SUB, OPR_ADD, rty))
01102 {
01103 simplified = _simplify_4adds(OPR_ADD,
01104 opnd1->get_opnd(0),
01105 OPCODE_operator(opnd1->get_opc()),
01106 opnd1->get_opnd(1),
01107 OPR_ADD,
01108 opnd2->get_opnd(0),
01109 OPCODE_operator(opnd2->get_opc()),
01110 opnd2->get_opnd(1),
01111 v);
01112 }
01113
01114 if (simplified == this &&
01115 Is_Rty_Opr2(opnd1, BINARY, OPR_SUB, OPR_ADD, rty))
01116 {
01117 simplified = _simplify_3adds(OPR_ADD,
01118 opnd1->get_opnd(0),
01119 OPCODE_operator(opnd1->get_opc()),
01120 opnd1->get_opnd(1),
01121 OPR_ADD,
01122 get_opnd(1),
01123 v);
01124 }
01125
01126 if (simplified == this &&
01127 Is_Rty_Opr2(opnd2, BINARY, OPR_SUB, OPR_ADD, rty))
01128 {
01129 simplified = _simplify_3adds(OPR_ADD,
01130 get_opnd(0),
01131 OPR_ADD,
01132 opnd2->get_opnd(0),
01133 OPCODE_operator(opnd2->get_opc()),
01134 opnd2->get_opnd(1),
01135 v);
01136 }
01137 }
01138
01139 if (simplified != this && !Is_Singular_Expr(simplified))
01140 simplified = simplified->simplify(v);
01141
01142 return simplified;
01143
01144 }
01145
01146
01147 VN_EXPR::PTR
01148 VN_BINARY_EXPR::_simplify_sub(CONST_PTR opnd1, CONST_PTR opnd2, VN *v)
01149 {
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160 PTR simplified = this;
01161 const MTYPE rty = OPCODE_rtype(_opc);
01162
01163 Is_True(OPCODE_operator(_opc) == OPR_SUB,
01164 ("Illegal opcode for VN_BINARY_EXPR::_simplify_add"));
01165
01166
01167
01168
01169
01170 if (Is_Rty_Opr2(opnd1, BINARY, OPR_SUB, OPR_ADD, rty) &&
01171 Is_Rty_Opr2(opnd2, BINARY, OPR_SUB, OPR_ADD, rty))
01172 {
01173 const OPERATOR opr3 = (OPCODE_operator(opnd2->get_opc()) == OPR_ADD?
01174 OPR_SUB : OPR_ADD);
01175
01176 simplified = _simplify_4adds(OPR_ADD,
01177 opnd1->get_opnd(0),
01178 OPCODE_operator(opnd1->get_opc()),
01179 opnd1->get_opnd(1),
01180 OPR_SUB,
01181 opnd2->get_opnd(0),
01182 opr3,
01183 opnd2->get_opnd(1),
01184 v);
01185 }
01186
01187 if (simplified == this &&
01188 Is_Rty_Opr2(opnd1, BINARY, OPR_SUB, OPR_ADD, rty))
01189 {
01190 simplified = _simplify_3adds(OPR_ADD,
01191 opnd1->get_opnd(0),
01192 OPCODE_operator(opnd1->get_opc()),
01193 opnd1->get_opnd(1),
01194 OPR_SUB,
01195 get_opnd(1),
01196 v);
01197 }
01198
01199 if (simplified == this &&
01200 Is_Rty_Opr2(opnd2, BINARY, OPR_SUB, OPR_ADD, rty))
01201 {
01202 const OPERATOR opr2 = (OPCODE_operator(opnd2->get_opc()) == OPR_ADD?
01203 OPR_SUB : OPR_ADD);
01204
01205 simplified = _simplify_3adds(OPR_ADD,
01206 get_opnd(0),
01207 OPR_SUB,
01208 opnd2->get_opnd(0),
01209 opr2,
01210 opnd2->get_opnd(1),
01211 v);
01212 }
01213
01214 if (simplified != this && !Is_Singular_Expr(simplified))
01215 simplified = simplified->simplify(v);
01216
01217 return simplified;
01218
01219 }
01220
01221
01222 VN_BINARY_EXPR *
01223 VN_BINARY_EXPR::Create(OPCODE opc,
01224 const VN_VALNUM &vn1,
01225 const VN_VALNUM &vn2)
01226 {
01227 Is_True((OPCODE_nkids(opc) == 2 || OPCODE_operator(opc) == OPR_CVTL ||
01228 OPCODE_operator(opc) == OPR_EXTRACT_BITS ) &&
01229 OPCODE_operator(opc) != OPR_COMMA &&
01230 OPCODE_operator(opc) != OPR_RCOMMA,
01231 ("Unexpected opcode in call to VN_BINARY_EXPR::Create()"));
01232
01233 VN_BINARY_EXPR *expr = (VN_BINARY_EXPR *)_Free->pop();
01234 if (expr == NULL)
01235 expr = CXX_NEW(VN_BINARY_EXPR(opc, vn1, vn2), _Mpool);
01236 else
01237 {
01238 expr->_opc = opc;
01239 expr->_vn[0] = vn1;
01240 expr->_vn[1] = vn2;
01241 }
01242 return expr;
01243 }
01244
01245
01246 VN_EXPR::PTR
01247 VN_BINARY_EXPR::simplify(VN *v)
01248 {
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262 const OPERATOR opr = OPCODE_operator(_opc);
01263 const MTYPE rty = Unify_Rty(opr, OPCODE_rtype(_opc));
01264 CONST_PTR opnd1 = v->valnum_expr(_vn[0]);
01265 CONST_PTR opnd2 = v->valnum_expr(_vn[1]);
01266 const BOOL is_integral =
01267 (OPERATOR_is_compare(opr)?
01268 MTYPE_is_integral(OPCODE_desc(_opc))
01269 #ifdef TARG_X8664 // bug 7554
01270 && ! MTYPE_is_vector(OPCODE_desc(_opc))
01271 #endif
01272 :
01273 MTYPE_is_integral(rty)
01274 #ifdef TARG_X8664 // bug 7554
01275 && ! MTYPE_is_vector(rty)
01276 #endif
01277 );
01278
01279 PTR simplified = this;
01280 INT64 intconst;
01281
01282
01283
01284
01285
01286 if (rty != OPCODE_rtype(_opc))
01287 _opc = OPCODE_make_op(opr, rty, OPCODE_desc(_opc));
01288
01289 if (has_bottom_opnd() || has_top_opnd())
01290 {
01291 simplified = Create_Unary(OPC_VPARM, VN_VALNUM::Bottom());
01292 }
01293 else if (Is_Literal_Expr(opnd1) && Is_Literal_Expr(opnd2))
01294 {
01295 PTR s = Create_Folded_Literal(_opc, opnd1, opnd2);
01296 if (s != NULL)
01297 simplified = s;
01298 }
01299 else if (is_integral)
01300 {
01301
01302
01303
01304 switch (opr)
01305 {
01306
01307
01308 case OPR_ADD:
01309 if (Is_Literal_Expr(opnd1) && Targ_Is_Zero(opnd1->get_tcon()))
01310 simplified = Create_Unary(OPC_VPARM, _vn[1]);
01311 else if (Is_Literal_Expr(opnd2) && Targ_Is_Zero(opnd2->get_tcon()))
01312 simplified = Create_Unary(OPC_VPARM, _vn[0]);
01313 break;
01314
01315 case OPR_SUB:
01316 if (_vn[0] == _vn[1])
01317 simplified = Create_Scalar_Literal_From_Int(rty, 0);
01318 else if (Is_Literal_Expr(opnd1) && Targ_Is_Zero(opnd1->get_tcon()))
01319 simplified = Create_Unary_Opr(OPR_NEG, _vn[1], rty);
01320 else if (Is_Literal_Expr(opnd2) && Targ_Is_Zero(opnd2->get_tcon()))
01321 simplified = Create_Unary(OPC_VPARM, _vn[0]);
01322 break;
01323
01324 case OPR_MPY:
01325 if (Is_Literal_Expr(opnd1))
01326 {
01327 intconst = Targ_To_Host(opnd1->get_tcon());
01328 if (MTYPE_is_signed(rty) && intconst == -1)
01329 simplified = Create_Unary_Opr(OPR_NEG, _vn[1], rty);
01330 else if (intconst == 0)
01331 simplified = Create_Scalar_Literal_From_Int(rty, 0);
01332 else if(intconst == 1)
01333 simplified = Create_Unary(OPC_VPARM, _vn[1]);
01334 }
01335 else if (Is_Literal_Expr(opnd2))
01336 {
01337 intconst = Targ_To_Host(opnd2->get_tcon());
01338 if (MTYPE_is_signed(rty) && intconst == -1)
01339 simplified = Create_Unary_Opr(OPR_NEG, _vn[0], rty);
01340 else if (intconst == 0)
01341 simplified = Create_Scalar_Literal_From_Int(rty, 0);
01342 else if(intconst == 1)
01343 simplified = Create_Unary(OPC_VPARM, _vn[0]);
01344 }
01345 break;
01346
01347 case OPR_DIV:
01348 if (Is_Literal_Expr(opnd2))
01349 {
01350 intconst = Targ_To_Host(opnd2->get_tcon());
01351 if (MTYPE_is_signed(rty) && intconst == -1)
01352 simplified = Create_Unary_Opr(OPR_NEG, _vn[0], rty);
01353 else if(intconst == 1)
01354 simplified = Create_Unary(OPC_VPARM, _vn[0]);
01355 }
01356 break;
01357
01358 case OPR_MOD:
01359 case OPR_REM:
01360 if (Is_Literal_Expr(opnd2))
01361 {
01362 intconst = Targ_To_Host(opnd2->get_tcon());
01363 if (intconst == -1 || intconst == 1)
01364 simplified = Create_Scalar_Literal_From_Int(rty, 0);
01365 }
01366 break;
01367
01368 case OPR_MAX:
01369 case OPR_MIN:
01370 if (_vn[0] == _vn[1])
01371 simplified = Create_Unary(OPC_VPARM, _vn[0]);
01372 break;
01373
01374 case OPR_EQ:
01375 case OPR_LE:
01376 case OPR_GE:
01377 if (_vn[0] == _vn[1])
01378 simplified = Create_Scalar_Literal_From_Int(rty, 1);
01379 break;
01380
01381 case OPR_NE:
01382 case OPR_LT:
01383 case OPR_GT:
01384 if (_vn[0] == _vn[1])
01385 simplified = Create_Scalar_Literal_From_Int(rty, 0);
01386 break;
01387
01388 case OPR_BAND:
01389 if (_vn[0] == _vn[1])
01390 {
01391 simplified = Create_Unary(OPC_VPARM, _vn[0]);
01392 }
01393 else if (Is_Literal_Expr(opnd2))
01394 {
01395 intconst = Targ_To_Host(opnd2->get_tcon());
01396 if (intconst == 0)
01397 simplified = Create_Scalar_Literal_From_Int(rty, 0);
01398 else if (All_Bits_Set(intconst, MTYPE_bit_size(rty)/8))
01399 simplified = Create_Unary(OPC_VPARM, _vn[0]);
01400 }
01401 else if (Is_Literal_Expr(opnd1))
01402 {
01403 intconst = Targ_To_Host(opnd1->get_tcon());
01404 if (intconst == 0)
01405 simplified = Create_Scalar_Literal_From_Int(rty, 0);
01406 else if (All_Bits_Set(intconst, MTYPE_bit_size(rty)/8))
01407 simplified = Create_Unary(OPC_VPARM, _vn[1]);
01408 }
01409 break;
01410
01411 case OPR_BIOR:
01412 if (_vn[0] == _vn[1])
01413 {
01414 simplified = Create_Unary(OPC_VPARM, _vn[0]);
01415 }
01416 else if (Is_Literal_Expr(opnd2))
01417 {
01418 intconst = Targ_To_Host(opnd2->get_tcon());
01419 if (intconst == 0)
01420 simplified = Create_Unary(OPC_VPARM, _vn[0]);
01421 else if (All_Bits_Set(intconst, MTYPE_bit_size(rty)/8))
01422 simplified = Create_Scalar_Literal_From_Int(rty, ~(0LL));
01423 }
01424 else if (Is_Literal_Expr(opnd1))
01425 {
01426 intconst = Targ_To_Host(opnd1->get_tcon());
01427 if (intconst == 0)
01428 simplified = Create_Unary(OPC_VPARM, _vn[1]);
01429 else if (All_Bits_Set(intconst, MTYPE_bit_size(rty)/8))
01430 simplified = Create_Scalar_Literal_From_Int(rty, ~(0LL));
01431 }
01432 break;
01433
01434 case OPR_BNOR:
01435 if (_vn[0] == _vn[1])
01436 {
01437 simplified = Create_Unary_Opr(OPR_BNOT, _vn[0], rty);
01438 }
01439 else if (Is_Literal_Expr(opnd2))
01440 {
01441 intconst = Targ_To_Host(opnd2->get_tcon());
01442 if (intconst == 0)
01443 simplified = Create_Unary_Opr(OPR_BNOT, _vn[0], rty);
01444 else if (All_Bits_Set(intconst, MTYPE_bit_size(rty)/8))
01445 simplified = Create_Scalar_Literal_From_Int(rty, 0);
01446 }
01447 else if (Is_Literal_Expr(opnd1))
01448 {
01449 intconst = Targ_To_Host(opnd1->get_tcon());
01450 if (intconst == 0)
01451 simplified = Create_Unary_Opr(OPR_BNOT, _vn[1], rty);
01452 else if (All_Bits_Set(intconst, MTYPE_bit_size(rty)/8))
01453 simplified = Create_Scalar_Literal_From_Int(rty, 0);
01454 }
01455 break;
01456
01457 case OPR_BXOR:
01458 if (_vn[0] == _vn[1])
01459 {
01460 simplified = Create_Scalar_Literal_From_Int(rty, 0);
01461 }
01462 else if (Is_Literal_Expr(opnd2))
01463 {
01464 intconst = Targ_To_Host(opnd2->get_tcon());
01465 if (intconst == 0)
01466 simplified = Create_Unary(OPC_VPARM, _vn[0]);
01467 else if (All_Bits_Set(intconst, MTYPE_bit_size(rty)/8))
01468 simplified = Create_Unary_Opr(OPR_BNOT, _vn[0], rty);
01469 }
01470 else if (Is_Literal_Expr(opnd1))
01471 {
01472 intconst = Targ_To_Host(opnd1->get_tcon());
01473 if (intconst == 0)
01474 simplified = Create_Unary(OPC_VPARM, _vn[1]);
01475 else if (All_Bits_Set(intconst, MTYPE_bit_size(rty)/8))
01476 simplified = Create_Unary_Opr(OPR_BNOT, _vn[1], rty);
01477 }
01478 break;
01479
01480 case OPR_LAND:
01481 case OPR_CAND:
01482 if (_vn[0] == _vn[1])
01483 {
01484 simplified = Create_Unary(OPC_VPARM, _vn[0]);
01485 }
01486 else if (Is_Literal_Expr(opnd2))
01487 {
01488 intconst = Targ_To_Host(opnd2->get_tcon());
01489 if (intconst == 0)
01490 simplified = Create_Scalar_Literal_From_Int(rty, 0);
01491 else if (intconst != 0)
01492 simplified = Create_Unary(OPC_VPARM, _vn[0]);
01493 }
01494 else if (Is_Literal_Expr(opnd1))
01495 {
01496 intconst = Targ_To_Host(opnd1->get_tcon());
01497 if (intconst == 0)
01498 simplified = Create_Scalar_Literal_From_Int(rty, 0);
01499 else if (intconst != 0)
01500 simplified = Create_Unary(OPC_VPARM, _vn[1]);
01501 }
01502 break;
01503
01504 case OPR_LIOR:
01505 case OPR_CIOR:
01506 if (_vn[0] == _vn[1])
01507 {
01508 simplified = Create_Unary(OPC_VPARM, _vn[0]);
01509 }
01510 else if (Is_Literal_Expr(opnd2))
01511 {
01512 intconst = Targ_To_Host(opnd2->get_tcon());
01513 if (intconst == 0)
01514 simplified = Create_Unary(OPC_VPARM, _vn[0]);
01515 else if (intconst != 0)
01516 simplified = Create_Literal(opnd2->get_tcon());
01517 }
01518 else if (Is_Literal_Expr(opnd1))
01519 {
01520 intconst = Targ_To_Host(opnd1->get_tcon());
01521 if (intconst == 0)
01522 simplified = Create_Unary(OPC_VPARM, _vn[1]);
01523 else if (intconst != 0)
01524 simplified = Create_Literal(opnd1->get_tcon());
01525 }
01526 break;
01527
01528 case OPR_SHL:
01529 case OPR_ASHR:
01530 case OPR_LSHR:
01531
01532
01533 if (Is_Literal_Expr(opnd2) && Targ_Is_Zero(opnd2->get_tcon()))
01534 simplified = Create_Unary(OPC_VPARM, _vn[0]);
01535 else if (Is_Literal_Expr(opnd1) && Targ_Is_Zero(opnd1->get_tcon()))
01536 simplified = Create_Scalar_Literal_From_Int(rty, 0);
01537 break;
01538
01539 }
01540
01541 if (simplified == this)
01542 {
01543
01544
01545 if (OPCODE_operator(_opc) == OPR_SUB)
01546 simplified = _simplify_sub(opnd1, opnd2, v);
01547 else if (OPCODE_operator(_opc) == OPR_ADD)
01548 simplified = _simplify_add(opnd1, opnd2, v);
01549 }
01550 }
01551
01552 if (simplified != this)
01553 free();
01554
01555 return simplified;
01556 }
01557
01558
01559
01560
01561
01562 VN_TERNARY_EXPR *
01563 VN_TERNARY_EXPR::Create(OPCODE opc,
01564 const VN_VALNUM &vn1,
01565 const VN_VALNUM &vn2,
01566 const VN_VALNUM &vn3)
01567 {
01568 Is_True(OPCODE_nkids(opc) == 3 || OPCODE_operator(opc) == OPR_COMPOSE_BITS,
01569 ("Unexpected opcode in call to VN_TERNARY_EXPR::Create()"));
01570
01571 VN_TERNARY_EXPR *expr = (VN_TERNARY_EXPR *)_Free->pop();
01572 if (expr == NULL)
01573 expr = CXX_NEW(VN_TERNARY_EXPR(opc, vn1, vn2, vn3), _Mpool);
01574 else
01575 {
01576 expr->_opc = opc;
01577 expr->_vn[0] = vn1;
01578 expr->_vn[1] = vn2;
01579 expr->_vn[2] = vn3;
01580 }
01581 return expr;
01582 }
01583
01584
01585 VN_EXPR::PTR
01586 VN_TERNARY_EXPR::simplify(VN *v)
01587 {
01588 PTR simplified = this;
01589 PTR cond = v->valnum_expr(_vn[0]);
01590 const OPERATOR opr = OPCODE_operator(_opc);
01591 const MTYPE rty = Unify_Rty(opr, OPCODE_rtype(_opc));
01592
01593
01594
01595
01596
01597 if (rty != OPCODE_rtype(_opc))
01598 _opc = OPCODE_make_op(opr, rty, OPCODE_desc(_opc));
01599
01600 if (has_bottom_opnd() || has_top_opnd())
01601 {
01602 simplified = Create_Unary(OPC_VPARM, VN_VALNUM::Bottom());
01603 }
01604 else if (opr == OPR_SELECT || opr == OPR_CSELECT)
01605 {
01606 if (Is_Literal_Expr(cond))
01607 {
01608 if (Targ_Is_Zero(cond->get_tcon()))
01609 simplified = Create_Unary(OPC_VPARM, _vn[2]);
01610 else
01611 simplified = Create_Unary(OPC_VPARM, _vn[1]);
01612 }
01613 else if (_vn[1] == _vn[2])
01614 {
01615
01616
01617 simplified = Create_Unary(OPC_VPARM, _vn[1]);
01618 }
01619 else if (_vn[0].is_top())
01620 {
01621
01622
01623
01624
01625
01626 simplified = Create_Unary(OPC_VPARM, _vn[1]);
01627 }
01628 }
01629
01630 if (simplified != this)
01631 free();
01632
01633 return simplified;
01634 }
01635
01636
01637
01638
01639
01640 VN_INTR_OP_EXPR *
01641 VN_INTR_OP_EXPR::Create(INTRINSIC intr_opc,
01642 UINT32 num_opnds)
01643 {
01644 VN_INTR_OP_EXPR *expr = (VN_INTR_OP_EXPR *)_Free->pop();
01645 if (expr == NULL)
01646 expr = CXX_NEW(VN_INTR_OP_EXPR(intr_opc, num_opnds), _Mpool);
01647 else
01648 {
01649 expr->_intr_opc = intr_opc;
01650 expr->_num_opnds = num_opnds;
01651
01652 if (num_opnds > 3)
01653 expr->_opnd_array = CXX_NEW_ARRAY(VN_VALNUM_PAIR, num_opnds, _Mpool);
01654 }
01655
01656 for (INT i = 0; i < num_opnds; i++)
01657 {
01658 expr->set_opnd(i, VN_VALNUM::Bottom());
01659 expr->set_opnd_vsym(i, VN_VALNUM::Bottom());
01660 }
01661
01662 return expr;
01663 }
01664
01665
01666 VN_EXPR::PTR
01667 VN_INTR_OP_EXPR::simplify(VN *v)
01668 {
01669 PTR simplified = this;
01670 const INT num_opnds = get_num_opnds();
01671
01672 if (has_bottom_opnd() || has_top_opnd())
01673 {
01674 simplified = Create_Unary(OPC_VPARM, VN_VALNUM::Bottom());
01675 }
01676 else if (num_opnds <= 8)
01677 {
01678 TCON arg_tconsts[8];
01679 INT i;
01680
01681 for (i = 0;
01682 (i < num_opnds && Is_Literal_Expr(v->valnum_expr(get_opnd(i))));
01683 i++)
01684 {
01685 arg_tconsts[i] = v->valnum_expr(get_opnd(i))->get_tcon();
01686 }
01687
01688 if (i == num_opnds)
01689 {
01690
01691
01692 BOOL folded = FALSE;
01693 TCON folded_tcon = Targ_IntrinsicOp(_intr_opc, arg_tconsts, &folded);
01694 if (folded)
01695 {
01696 simplified = Create_Literal(folded_tcon);
01697 }
01698 }
01699 }
01700
01701 if (simplified != this)
01702 free();
01703
01704 return simplified;
01705 }
01706
01707
01708
01709
01710
01711 VN_PHI_EXPR *
01712 VN_PHI_EXPR::Create(UINT32 num_opnds,
01713 IDTYPE block_id,
01714 PHI_TAG phi_tag)
01715 {
01716 VN_PHI_EXPR *expr = (VN_PHI_EXPR *)_Free->pop();
01717 if (expr == NULL)
01718 expr = CXX_NEW(VN_PHI_EXPR(num_opnds, block_id, phi_tag), _Mpool);
01719 else
01720 {
01721 expr->_num_opnds = num_opnds;
01722 expr->_block_id = block_id;
01723 expr->_phi_tag = phi_tag;
01724 }
01725
01726 if (num_opnds > 3)
01727 expr->_vn_array = CXX_NEW_ARRAY(VN_VALNUM, num_opnds, _Mpool);
01728
01729 for (INT i = 0; i < num_opnds; i++)
01730 expr->set_opnd(i, VN_VALNUM::Bottom());
01731
01732 return expr;
01733 }
01734
01735
01736 VN_EXPR::PTR
01737 VN_PHI_EXPR::simplify(VN *)
01738 {
01739 PTR simplified = this;
01740
01741 if (has_bottom_opnd())
01742 {
01743 simplified = Create_Unary(OPC_VPARM, VN_VALNUM::Bottom());
01744 }
01745 else
01746 {
01747
01748
01749
01750
01751
01752
01753
01754 VN_VALNUM vn = get_opnd(0);
01755 BOOL match = TRUE;
01756
01757 for (INT i = 1; match && i < get_num_opnds(); i++)
01758 {
01759 match = vn.equivalent_to(get_opnd(i));
01760 if (match && vn.is_top())
01761 vn = get_opnd(i);
01762 }
01763 if (match)
01764 simplified = Create_Unary(OPC_VPARM, vn);
01765 else if (has_top_opnd())
01766 simplified = Create_Unary(OPC_VPARM, VN_VALNUM::Bottom());
01767 }
01768
01769 if (simplified != this)
01770 free();
01771
01772 return simplified;
01773 }
01774
01775
01776
01777
01778
01779 VN_LDA_ADDR_EXPR *
01780 VN_LDA_ADDR_EXPR::Create(INT32 lda_cr_id)
01781 {
01782 VN_LDA_ADDR_EXPR *expr = (VN_LDA_ADDR_EXPR *)_Free->pop();
01783 if (expr == NULL)
01784 expr = CXX_NEW(VN_LDA_ADDR_EXPR(lda_cr_id), _Mpool);
01785 else
01786 expr->_lda_cr_id = lda_cr_id;
01787 return expr;
01788 }
01789
01790
01791
01792
01793
01794 VN_ARRAY_ADDR_EXPR *
01795 VN_ARRAY_ADDR_EXPR::Create(WN_ESIZE esize, INT32 num_dims)
01796 {
01797 VN_ARRAY_ADDR_EXPR *expr = (VN_ARRAY_ADDR_EXPR *)_Free->pop();
01798 const UINT32 num_opnds = 1 + 2*num_dims;
01799
01800 if (expr == NULL)
01801 expr = CXX_NEW(VN_ARRAY_ADDR_EXPR(esize, num_dims), _Mpool);
01802 else
01803 {
01804 expr->_num_opnds = num_opnds;
01805 expr->_esize = esize;
01806
01807 if (num_opnds > 3)
01808 expr->_vn_array = CXX_NEW_ARRAY(VN_VALNUM, num_opnds, _Mpool);
01809 }
01810
01811 for (INT i = 0; i < num_opnds; i++)
01812 expr->set_opnd(i, VN_VALNUM::Bottom());
01813
01814 return expr;
01815 }
01816
01817
01818 VN_EXPR::PTR
01819 VN_ARRAY_ADDR_EXPR::simplify(VN *)
01820 {
01821 PTR simplified;
01822
01823 if (has_bottom_opnd() || has_top_opnd())
01824 {
01825 simplified = Create_Unary(OPC_VPARM, VN_VALNUM::Bottom());
01826 free();
01827 }
01828 else
01829 {
01830 simplified = this;
01831 }
01832 return simplified;
01833 }
01834
01835
01836
01837
01838
01839
01840 VN_MEMLOC_EXPR *
01841 VN_MEMLOC_EXPR::Create(MTYPE dsctype,
01842 const VN_VALNUM &bytesize,
01843 const VN_VALNUM &offset,
01844 const VN_VALNUM &base_addr,
01845 const VN_VALNUM &vsym_valnum)
01846 {
01847
01848 VN_MEMLOC_EXPR *expr = (VN_MEMLOC_EXPR *)_Free->pop();
01849 if (expr == NULL)
01850 expr = CXX_NEW(VN_MEMLOC_EXPR(dsctype,
01851 bytesize, offset, base_addr, vsym_valnum),
01852 _Mpool);
01853 else
01854 {
01855 expr->_dsctype = dsctype;
01856 expr->_bytesize = bytesize;
01857 expr->_offset = offset;
01858 expr->_base_addr = base_addr;
01859 expr->_vsym_valnum = vsym_valnum;
01860 }
01861 return expr;
01862 }
01863
01864
01865 VN_EXPR::PTR
01866 VN_MEMLOC_EXPR::simplify(VN *v)
01867 {
01868 PTR simplified;
01869
01870 if (has_bottom_opnd() || has_top_opnd())
01871 {
01872 simplified = Create_Unary(OPC_VPARM, VN_VALNUM::Bottom());
01873 }
01874 else
01875 {
01876 PTR offset_expr = v->valnum_expr(_offset);
01877
01878 if (!Is_Literal_Expr(offset_expr) ||
01879 Targ_To_Host(offset_expr->get_tcon()) != 0)
01880 {
01881
01882
01883 PTR address = Create_Binary_Opr(OPR_ADD,
01884 _offset, _base_addr,
01885 Pointer_type, MTYPE_V);
01886 PTR addr_simplified = address->simplify(v);
01887
01888 if (addr_simplified->get_kind() == VN_EXPR::UNARY &&
01889 addr_simplified->get_opc() == OPC_VPARM)
01890 {
01891 VN_VALNUM base_addr = addr_simplified->get_opnd(0);
01892 VN_VALNUM zero_ofst =
01893 v->valnum_integer(Host_To_Targ(Pointer_type, 0));
01894
01895 simplified =
01896 VN_EXPR::Create_Memloc(_dsctype,
01897 _bytesize,
01898 zero_ofst,
01899 base_addr,
01900 _vsym_valnum);
01901 }
01902 else
01903 {
01904 simplified = this;
01905 }
01906
01907
01908
01909 addr_simplified->free();
01910 }
01911 else
01912 {
01913 simplified = this;
01914 }
01915 }
01916
01917 if (simplified != this)
01918 free();
01919
01920 return simplified;
01921 }
01922
01923
01924 #ifdef KEY
01925
01926
01927
01928 VN_CALL_OP_EXPR *
01929 VN_CALL_OP_EXPR::Create(ST_IDX aux_id,
01930 UINT32 num_opnds)
01931 {
01932 VN_CALL_OP_EXPR *expr = (VN_CALL_OP_EXPR *)_Free->pop();
01933 if (expr == NULL)
01934 expr = CXX_NEW(VN_CALL_OP_EXPR(aux_id, num_opnds), _Mpool);
01935 else
01936 {
01937 expr->_aux_id = aux_id;
01938 expr->_num_opnds = num_opnds;
01939
01940 if (num_opnds > 3)
01941 expr->_opnd_array = CXX_NEW_ARRAY(VN_VALNUM_PAIR, num_opnds, _Mpool);
01942 }
01943
01944 for (INT i = 0; i < num_opnds; i++)
01945 {
01946 expr->set_opnd(i, VN_VALNUM::Bottom());
01947 expr->set_opnd_vsym(i, VN_VALNUM::Bottom());
01948 }
01949
01950 return expr;
01951 }
01952
01953
01954 VN_EXPR::PTR
01955 VN_CALL_OP_EXPR::simplify(VN *)
01956 {
01957 PTR simplified;
01958
01959 if (has_bottom_opnd() || has_top_opnd())
01960 {
01961 simplified = Create_Unary(OPC_VPARM, VN_VALNUM::Bottom());
01962 free();
01963 }
01964 else
01965 {
01966 simplified = this;
01967 }
01968 return simplified;
01969 }
01970 #endif