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
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 #ifndef opt_vn_expr_taxonomy_INCLUDED
00115 #define opt_vn_expr_taxonomy_INCLUDED "opt_vn_expr_taxonomy.h"
00116
00117 #include "opt_vn_expr.h"
00118 #include "intrn_info.h"
00119 #include "wutil.h"
00120
00121 #ifdef __STL_USE_NAMESPACES
00122 using std::pair;
00123 #endif
00124
00125 typedef pair<VN_VALNUM,VN_VALNUM> VN_VALNUM_PAIR;
00126
00127
00128
00129
00130 class VN_LITERAL_EXPR;
00131 class VN_UNARY_EXPR;
00132 class VN_BINARY_EXPR;
00133 class VN_TERNARY_EXPR;
00134 class VN_INTR_OP_EXPR;
00135 class VN_PHI_EXPR;
00136 class VN_LDA_ADDR_EXPR;
00137 class VN_ARRAY_ADDR_EXPR;
00138 class VN_MEMLOC_EXPR;
00139
00140 inline void
00141 Switch_Vn_Opnd(VN_VALNUM &vn1, VN_VALNUM &vn2)
00142 {
00143 VN_VALNUM tmp = vn1;
00144 vn1 = vn2;
00145 vn2 = tmp;
00146 }
00147
00148
00149
00150
00151 class FREE_STACK
00152 {
00153 private:
00154
00155 typedef SEGMENTED_ARRAY<VN_EXPR::PTR, VN_BUFFER_CHUNKSIZE> ARRAY_OF_EXPR;
00156
00157 ARRAY_OF_EXPR _stack;
00158 INT32 _top;
00159 MEM_POOL *_mpool;
00160
00161 public:
00162
00163 FREE_STACK(MEM_POOL *mpool = Malloc_Mem_Pool):
00164 _stack(mpool), _top(-1), _mpool(mpool) {}
00165
00166 ~FREE_STACK()
00167 {
00168 for (INT32 i = 0; i <= _top; i++)
00169 {
00170
00171
00172 CXX_DELETE(_stack[i], _mpool);
00173 }
00174 _stack.Delete_last(_stack.Size());
00175 _top = -1;
00176 }
00177
00178 void push(VN_EXPR::PTR expr)
00179 {
00180 UINT new_top = _top + 1;
00181 if (new_top == _stack.Size())
00182 _stack.New_entry(new_top) = expr;
00183 else
00184 _stack[new_top] = expr;
00185 _top = new_top;
00186 }
00187
00188 VN_EXPR::PTR pop()
00189 {
00190 VN_EXPR::PTR expr;
00191
00192 if (_top >= 0)
00193 {
00194 expr = _stack[_top];
00195 _top -= 1;
00196 }
00197 else
00198 expr = NULL;
00199 return expr;
00200 }
00201 };
00202
00203
00204
00205
00206
00207 class VN_LITERAL_EXPR : public VN_EXPR
00208 {
00209 private:
00210
00211 static FREE_STACK *_Free;
00212
00213 TCON _tcon;
00214
00215 VN_LITERAL_EXPR(const TCON &tcon) : _tcon(tcon) {}
00216
00217 public:
00218
00219 static void Init_Free_List() {_Free = CXX_NEW(FREE_STACK(_Mpool), _Mpool);}
00220 static void Reclaim_Free_List() {CXX_DELETE(_Free, _Mpool); _Free = NULL;}
00221
00222 static VN_LITERAL_EXPR *Create(const TCON &tcon)
00223 {
00224 VN_LITERAL_EXPR *expr = (VN_LITERAL_EXPR *)_Free->pop();
00225 if (expr == NULL)
00226 expr = CXX_NEW(VN_LITERAL_EXPR(tcon), _Mpool);
00227 else
00228 expr->_tcon = tcon;
00229 return expr;
00230 }
00231
00232 void free()
00233 {
00234 _Free->push(this);
00235 }
00236
00237 KIND get_kind() const
00238 {
00239 return LITERAL;
00240 }
00241
00242 UINT32 get_num_opnds() const
00243 {
00244 return 0;
00245 }
00246
00247 BOOL has_top_opnd() const
00248 {
00249 return FALSE;
00250 }
00251
00252 BOOL has_bottom_opnd() const
00253 {
00254 return FALSE;
00255 }
00256
00257 const TCON &get_tcon() const
00258 {
00259 return _tcon;
00260 }
00261
00262 PTR simplify(VN *)
00263 {
00264 return this;
00265 }
00266
00267 size_t hash()
00268 {
00269 INT64 hval;
00270 if (!Targ_Is_Integral(_tcon, &hval))
00271 hval = Hash_TCON(&_tcon, INT32_MAX);
00272 return hval;
00273 }
00274
00275 BOOL is_equal_to(CONST_PTR expr) const;
00276
00277 void print(FILE *fp = stderr) const
00278 {
00279 fprintf(fp, "%s_const", MTYPE_name(TCON_ty(_tcon)));
00280 fprintf(fp, "(%s)", Targ_Print(NULL, _tcon));
00281 }
00282
00283 };
00284
00285
00286
00287
00288
00289 class VN_UNARY_EXPR : public VN_EXPR
00290 {
00291 private:
00292
00293 static FREE_STACK *_Free;
00294
00295 OPCODE _opc;
00296 VN_VALNUM _vn;
00297
00298 VN_UNARY_EXPR(OPCODE opc, const VN_VALNUM &vn):
00299 _opc(opc), _vn(vn) {}
00300
00301 public:
00302
00303 static void Init_Free_List() {_Free = CXX_NEW(FREE_STACK(_Mpool), _Mpool);}
00304 static void Reclaim_Free_List() {CXX_DELETE(_Free, _Mpool); _Free = NULL;}
00305
00306 static VN_UNARY_EXPR *Create(OPCODE opc, const VN_VALNUM &vn);
00307
00308 void free()
00309 {
00310 _Free->push(this);
00311 }
00312
00313 KIND get_kind() const
00314 {
00315 return UNARY;
00316 }
00317
00318 UINT32 get_num_opnds() const
00319 {
00320 return 1;
00321 }
00322
00323 BOOL has_top_opnd() const
00324 {
00325 return _vn.is_top();
00326 }
00327
00328 BOOL has_bottom_opnd() const
00329 {
00330 return _vn.is_bottom();
00331 }
00332
00333 VN_VALNUM get_opnd(UINT i=0) const
00334 {
00335 Is_True(i < get_num_opnds(), ("Erroneous VN_UNARY_EXPR::opnd access"));
00336 return _vn;
00337 }
00338
00339 OPCODE get_opc() const
00340 {
00341 return _opc;
00342 }
00343
00344 void set_opnd(UINT32 i, VN_VALNUM vn)
00345 {
00346 Is_True(i < get_num_opnds(), ("Erroneous VN_UNARY_EXPR::opnd access"));
00347 _vn = vn;
00348 }
00349
00350 PTR simplify(VN *v);
00351
00352 size_t hash()
00353 {
00354 OPERATOR opr = OPCODE_operator(_opc);
00355 Is_True(opr != OPR_PARM && !has_bottom_opnd() && !has_top_opnd(),
00356 ("Cannot hash() with Top() or Bottom() operand!"));
00357 return _vn.ordinal() + (_opc << 4);
00358 }
00359
00360 BOOL is_equal_to(CONST_PTR expr) const
00361 {
00362 return (expr != NULL &&
00363 expr->get_kind() == UNARY &&
00364 expr->get_opc() == _opc &&
00365 expr->get_opnd(0) == _vn);
00366 }
00367
00368 void print(FILE *fp = stderr) const
00369 {
00370 fprintf(fp, "%s(", OPCODE_name(_opc));
00371 _vn.print(fp);
00372 fputs(")", fp);
00373 }
00374
00375 };
00376
00377
00378
00379
00380
00381 class VN_BINARY_EXPR : public VN_EXPR
00382 {
00383 private:
00384
00385 static FREE_STACK *_Free;
00386
00387 OPCODE _opc;
00388 VN_VALNUM _vn[2];
00389
00390 void _canonicalize();
00391 PTR _fold_2literals(OPERATOR opr1,
00392 CONST_PTR literal1,
00393 OPERATOR opr2,
00394 CONST_PTR literal2);
00395 PTR _simplify_2literals(OPERATOR opr1,
00396 CONST_PTR literal1,
00397 OPERATOR opr2,
00398 CONST_PTR literal2,
00399 OPERATOR opr3,
00400 VN_VALNUM vn3,
00401 VN *v);
00402 PTR _simplify_3adds(OPERATOR opr0,
00403 VN_VALNUM vn0,
00404 OPERATOR opr1,
00405 VN_VALNUM vn1,
00406 OPERATOR opr2,
00407 VN_VALNUM vn2,
00408 VN *v);
00409 PTR _simplify_4adds(OPERATOR opr0,
00410 VN_VALNUM vn0,
00411 OPERATOR opr1,
00412 VN_VALNUM vn1,
00413 OPERATOR opr2,
00414 VN_VALNUM vn2,
00415 OPERATOR opr3,
00416 VN_VALNUM vn3,
00417 VN *v);
00418 PTR _simplify_add(CONST_PTR opnd1, CONST_PTR opnd2, VN *v);
00419 PTR _simplify_sub(CONST_PTR opnd1, CONST_PTR opnd2, VN *v);
00420
00421 VN_BINARY_EXPR(OPCODE opc, const VN_VALNUM &vn1, const VN_VALNUM &vn2):
00422 _opc(opc)
00423 {
00424 _vn[0] = vn1; _vn[1] = vn2;
00425 }
00426
00427 public:
00428
00429 static void Init_Free_List() {_Free = CXX_NEW(FREE_STACK(_Mpool), _Mpool);}
00430 static void Reclaim_Free_List() {CXX_DELETE(_Free, _Mpool); _Free = NULL;}
00431
00432 static VN_BINARY_EXPR *Create(OPCODE opc,
00433 const VN_VALNUM &vn1,
00434 const VN_VALNUM &vn2);
00435
00436 void free()
00437 {
00438 _Free->push(this);
00439 }
00440
00441 KIND get_kind() const
00442 {
00443 return BINARY;
00444 }
00445
00446 UINT32 get_num_opnds() const
00447 {
00448 return 2;
00449 }
00450
00451 BOOL has_top_opnd() const
00452 {
00453 return _vn[0].is_top() || _vn[1].is_top();
00454 }
00455
00456 BOOL has_bottom_opnd() const
00457 {
00458 return _vn[0].is_bottom() || _vn[1].is_bottom();
00459 }
00460
00461 VN_VALNUM get_opnd(UINT i=0) const
00462 {
00463 Is_True(i < get_num_opnds(), ("Erroneous VN_BINARY_EXPR::opnd access"));
00464 return _vn[i];
00465 }
00466
00467 OPCODE get_opc() const
00468 {
00469 return _opc;
00470 }
00471
00472 void set_opnd(UINT32 i, VN_VALNUM vn)
00473 {
00474 Is_True(i < get_num_opnds(), ("Erroneous VN_BINARY_EXPR::opnd access"));
00475 _vn[i] = vn;
00476 }
00477
00478 PTR simplify(VN *v);
00479
00480 size_t hash()
00481 {
00482 Is_True(!has_bottom_opnd() && !has_top_opnd(),
00483 ("Cannot hash() with Top() or Bottom() operand!"));
00484 _canonicalize();
00485 return _opc + (_vn[0].ordinal() << 4) + (_vn[1].ordinal() << 8);
00486 }
00487
00488 BOOL is_equal_to(CONST_PTR expr) const
00489 {
00490 return (expr != NULL &&
00491 expr->get_kind() == BINARY &&
00492 expr->get_opc() == _opc &&
00493 expr->get_opnd(0) == _vn[0] &&
00494 expr->get_opnd(1) == _vn[1]);
00495 }
00496
00497 void print(FILE *fp = stderr) const
00498 {
00499 fprintf(fp, "%s(", OPCODE_name(_opc));
00500 _vn[0].print(fp);
00501 fputs(", ", fp);
00502 _vn[1].print(fp);
00503 fputs(")", fp);
00504 }
00505
00506 };
00507
00508
00509
00510
00511
00512 class VN_TERNARY_EXPR : public VN_EXPR
00513 {
00514 private:
00515
00516 static FREE_STACK *_Free;
00517
00518 OPCODE _opc;
00519 VN_VALNUM _vn[3];
00520
00521 VN_TERNARY_EXPR(OPCODE opc,
00522 const VN_VALNUM &vn1,
00523 const VN_VALNUM &vn2,
00524 const VN_VALNUM &vn3):
00525 _opc(opc)
00526 {
00527 _vn[0] = vn1; _vn[1] = vn2; _vn[2] = vn3;
00528 }
00529
00530 public:
00531
00532 static void Init_Free_List() {_Free = CXX_NEW(FREE_STACK(_Mpool), _Mpool);}
00533 static void Reclaim_Free_List() {CXX_DELETE(_Free, _Mpool); _Free = NULL;}
00534
00535 static VN_TERNARY_EXPR *Create(OPCODE opc,
00536 const VN_VALNUM &vn1,
00537 const VN_VALNUM &vn2,
00538 const VN_VALNUM &vn3);
00539
00540 void free()
00541 {
00542 _Free->push(this);
00543 }
00544
00545 KIND get_kind() const
00546 {
00547 return TERNARY;
00548 }
00549
00550 UINT32 get_num_opnds() const
00551 {
00552 return 3;
00553 }
00554
00555 VN_VALNUM get_opnd(UINT i=0) const
00556 {
00557 Is_True(i < get_num_opnds(), ("Erroneous VN_TERNARY_EXPR::opnd access"));
00558 return _vn[i];
00559 }
00560
00561 BOOL has_top_opnd() const
00562 {
00563 return _vn[0].is_top() || _vn[1].is_top() || _vn[2].is_top();
00564 }
00565
00566 BOOL has_bottom_opnd() const
00567 {
00568 return _vn[0].is_bottom() || _vn[1].is_bottom() || _vn[2].is_bottom();
00569 }
00570
00571 OPCODE get_opc() const
00572 {
00573 return _opc;
00574 }
00575
00576 void set_opnd(UINT32 i, VN_VALNUM vn)
00577 {
00578 Is_True(i < get_num_opnds(), ("Erroneous VN_TERNARY_EXPR::opnd access"));
00579 _vn[i] = vn;
00580 }
00581
00582 PTR simplify(VN *v);
00583
00584 size_t hash()
00585 {
00586 Is_True(!has_bottom_opnd() && !has_top_opnd(),
00587 ("Cannot hash() with Top() or Bottom() operand!"));
00588 return
00589 _opc +
00590 (_vn[0].ordinal() << 4) +
00591 (_vn[1].ordinal() << 6) +
00592 (_vn[2].ordinal() << 8);
00593 }
00594
00595 BOOL is_equal_to(CONST_PTR expr) const
00596 {
00597 return (expr != NULL &&
00598 expr->get_kind() == TERNARY &&
00599 expr->get_opc() == _opc &&
00600 expr->get_opnd(0) == _vn[0] &&
00601 expr->get_opnd(1) == _vn[1] &&
00602 expr->get_opnd(2) == _vn[2]);
00603 }
00604
00605 void print(FILE *fp = stderr) const
00606 {
00607 fprintf(fp, "%s(", OPCODE_name(_opc));
00608 _vn[0].print(fp);
00609 fputs(", ", fp);
00610 _vn[1].print(fp);
00611 fputs(", ", fp);
00612 _vn[2].print(fp);
00613 fputs(")", fp);
00614 }
00615
00616 };
00617
00618
00619
00620
00621
00622 class VN_INTR_OP_EXPR : public VN_EXPR
00623 {
00624 private:
00625
00626 static FREE_STACK *_Free;
00627
00628 INTRINSIC _intr_opc;
00629 UINT32 _num_opnds;
00630 VN_VALNUM_PAIR _opnd[3];
00631 VN_VALNUM_PAIR *_opnd_array;
00632
00633 VN_INTR_OP_EXPR(INTRINSIC intr_opc,
00634 UINT32 num_opnds):
00635 _intr_opc(intr_opc), _num_opnds(num_opnds), _opnd_array(NULL)
00636 {
00637 if (num_opnds > 3)
00638 _opnd_array = CXX_NEW_ARRAY(VN_VALNUM_PAIR, num_opnds, _Mpool);
00639 for (INT i = 0; i < num_opnds; i++)
00640 {
00641 set_opnd(i, VN_VALNUM::Bottom());
00642 set_opnd_vsym(i, VN_VALNUM::Bottom());
00643 }
00644 }
00645
00646 public:
00647
00648 static void Init_Free_List() {_Free = CXX_NEW(FREE_STACK(_Mpool), _Mpool);}
00649 static void Reclaim_Free_List() {CXX_DELETE(_Free, _Mpool); _Free = NULL;}
00650
00651 static VN_INTR_OP_EXPR *Create(INTRINSIC intr_opc,
00652 UINT32 num_opnds);
00653
00654 void free()
00655 {
00656 if (_opnd_array != NULL)
00657 {
00658 CXX_DELETE_ARRAY(_opnd_array, _Mpool);
00659 _opnd_array = NULL;
00660 }
00661 _Free->push(this);
00662 }
00663
00664 KIND get_kind() const
00665 {
00666 return INTR_OP;
00667 }
00668
00669 UINT32 get_num_opnds() const
00670 {
00671 return _num_opnds;
00672 }
00673
00674 VN_VALNUM get_opnd(UINT i) const
00675 {
00676 Is_True(i < get_num_opnds(), ("Erroneous VN_INTR_OP_EXPR::opnd access"));
00677 return (_opnd_array == NULL?
00678 _opnd[i].first : _opnd_array[i].first);
00679 }
00680
00681 VN_VALNUM get_vsym(UINT i=0) const
00682 {
00683 Is_True(i < get_num_opnds(), ("Erroneous VN_INTR_OP_EXPR::vsym access"));
00684 return (_opnd_array == NULL?
00685 _opnd[i].second : _opnd_array[i].second);
00686 }
00687
00688 BOOL has_top_opnd() const
00689 {
00690 INT i = 0;
00691 while(i < get_num_opnds() && get_opnd(i) != VN_VALNUM::Top()) i++;
00692 return (i < get_num_opnds());
00693 }
00694
00695 BOOL has_bottom_opnd() const
00696 {
00697 INT i = 0;
00698 while(i < get_num_opnds() && get_opnd(i) != VN_VALNUM::Bottom()) i++;
00699 return (i < get_num_opnds());
00700 }
00701
00702 INTRINSIC get_intr_opc() const
00703 {
00704 return _intr_opc;
00705 }
00706
00707 void set_opnd(UINT32 i, VN_VALNUM vn)
00708 {
00709 Is_True(i < get_num_opnds(), ("Erroneous VN_INTR_OP_EXPR::opnd access"));
00710 if (_opnd_array == NULL)
00711 _opnd[i].first = vn;
00712 else
00713 _opnd_array[i].first = vn;
00714 }
00715
00716 void set_opnd_vsym(UINT32 i, VN_VALNUM vn)
00717 {
00718 Is_True(i < get_num_opnds(), ("Erroneous VN_INTR_OP_EXPR::vsym access"));
00719 if (_opnd_array == NULL)
00720 _opnd[i].second = vn;
00721 else
00722 _opnd_array[i].second = vn;
00723 }
00724
00725 PTR simplify(VN *v);
00726
00727 size_t hash()
00728 {
00729 size_t hashval = _intr_opc;
00730 Is_True(!has_bottom_opnd() && !has_top_opnd(),
00731 ("Cannot hash() with Top() or Bottom() operand!"));
00732 for (INT i = 0; i < get_num_opnds(); i++)
00733 {
00734 hashval += (get_opnd(i).ordinal() << 4);
00735 hashval += (get_vsym(i).ordinal() << 4);
00736 }
00737 return hashval;
00738 }
00739
00740 BOOL is_equal_to(CONST_PTR expr) const
00741 {
00742 BOOL truth = (expr != NULL &&
00743 expr->get_kind() == INTR_OP &&
00744 expr->get_num_opnds() == _num_opnds &&
00745 expr->get_intr_opc() == _intr_opc);
00746
00747 for (INT i = 0; truth && i < get_num_opnds(); i++)
00748 truth = (expr->get_opnd(i) == get_opnd(i) &&
00749 expr->get_vsym(i) == get_vsym(i));
00750 return truth;
00751 }
00752
00753 void print(FILE *fp = stderr) const
00754 {
00755 fprintf(fp, "%s(", INTRINSIC_name(_intr_opc));
00756 for (INT i = 0; i < get_num_opnds(); i++)
00757 {
00758 if (i > 0)
00759 fputs(", ", fp);
00760 fputs("<", fp);
00761 get_opnd(i).print(fp);
00762 fputs(",", fp);
00763 get_vsym(i).print(fp);
00764 fputs(">", fp);
00765 }
00766 fputs(")", fp);
00767 }
00768
00769 };
00770
00771
00772
00773
00774
00775 class VN_PHI_EXPR : public VN_EXPR
00776 {
00777 private:
00778
00779 static FREE_STACK *_Free;
00780
00781 IDTYPE _block_id;
00782 PHI_TAG _phi_tag;
00783 UINT32 _num_opnds;
00784 VN_VALNUM _vn[3];
00785 VN_VALNUM *_vn_array;
00786
00787 VN_PHI_EXPR(UINT32 num_opnds, IDTYPE block_id, PHI_TAG phi_tag):
00788 _num_opnds(num_opnds),
00789 _block_id(block_id),
00790 _phi_tag(phi_tag),
00791 _vn_array(NULL)
00792 {
00793 if (num_opnds > 3)
00794 _vn_array = CXX_NEW_ARRAY(VN_VALNUM, num_opnds, _Mpool);
00795 for (INT i = 0; i < num_opnds; i++) set_opnd(i, VN_VALNUM::Bottom());
00796 }
00797
00798 public:
00799
00800 static void Init_Free_List() {_Free = CXX_NEW(FREE_STACK(_Mpool), _Mpool);}
00801 static void Reclaim_Free_List() {CXX_DELETE(_Free, _Mpool); _Free = NULL;}
00802
00803 static VN_PHI_EXPR *Create(UINT32 num_opnds,
00804 IDTYPE block_id,
00805 PHI_TAG phi_tag);
00806
00807 void free()
00808 {
00809 if (_vn_array != NULL)
00810 {
00811 CXX_DELETE_ARRAY(_vn_array, _Mpool);
00812 _vn_array = NULL;
00813 }
00814 _Free->push(this);
00815 }
00816
00817 KIND get_kind() const
00818 {
00819 return PHI;
00820 }
00821
00822 UINT32 get_num_opnds() const
00823 {
00824 return _num_opnds;
00825 }
00826
00827 VN_VALNUM get_opnd(UINT i=0) const
00828 {
00829 Is_True(i < get_num_opnds(), ("Erroneous VN_PHI_EXPR::opnd access"));
00830 return (_vn_array == NULL? _vn[i] : _vn_array[i]);
00831 }
00832
00833 BOOL has_top_opnd() const
00834 {
00835 INT i = 0;
00836 while(i < get_num_opnds() && get_opnd(i) != VN_VALNUM::Top()) i++;
00837 return (i < get_num_opnds());
00838 }
00839
00840 BOOL has_bottom_opnd() const
00841 {
00842 INT i = 0;
00843 while(i < get_num_opnds() && get_opnd(i) != VN_VALNUM::Bottom()) i++;
00844 return (i < get_num_opnds());
00845 }
00846
00847 PHI_TAG get_phi_tag() const
00848 {
00849 return _phi_tag;
00850 }
00851
00852 IDTYPE get_block_id() const
00853 {
00854 return _block_id;
00855 }
00856
00857 void set_opnd(UINT32 i, VN_VALNUM vn)
00858 {
00859 Is_True(i < get_num_opnds(), ("Erroneous VN_PHI_EXPR::opnd access"));
00860 if (_vn_array == NULL)
00861 _vn[i] = vn;
00862 else
00863 _vn_array[i] = vn;
00864 }
00865
00866 PTR simplify(VN *v);
00867
00868 size_t hash()
00869 {
00870 size_t hashval = _block_id;
00871 Is_True(!has_bottom_opnd() && !has_top_opnd(),
00872 ("Cannot hash() with Top() or Bottom() operand!"));
00873 for (INT i = 0; i < get_num_opnds(); i++)
00874 hashval += (get_opnd(i).ordinal() << 4);
00875 return hashval;
00876 }
00877
00878 BOOL is_equal_to(CONST_PTR expr) const
00879 {
00880 BOOL truth = (expr != NULL &&
00881 expr->get_kind() == PHI &&
00882 expr->get_num_opnds() == _num_opnds &&
00883 expr->get_block_id() == _block_id &&
00884 expr->get_phi_tag() == _phi_tag);
00885
00886 for (INT i = 0; truth && i < get_num_opnds(); i++)
00887 truth = (expr->get_opnd(i) == get_opnd(i));
00888 return truth;
00889 }
00890
00891 void print(FILE *fp = stderr) const
00892 {
00893 fprintf(fp, "Phi[blck=%d](", (INT32)_block_id);
00894 for (INT i = 0; i < get_num_opnds(); i++)
00895 {
00896 if (i > 0)
00897 fputs(", ", fp);
00898 get_opnd(i).print(fp);
00899 }
00900 fputs(")", fp);
00901 }
00902
00903 };
00904
00905
00906
00907
00908
00909 class VN_LDA_ADDR_EXPR : public VN_EXPR
00910 {
00911 private:
00912
00913 static FREE_STACK *_Free;
00914
00915 INT32 _lda_cr_id;
00916
00917 VN_LDA_ADDR_EXPR(INT32 lda_cr_id): _lda_cr_id(lda_cr_id) {}
00918
00919 public:
00920
00921 static void Init_Free_List() {_Free = CXX_NEW(FREE_STACK(_Mpool), _Mpool);}
00922 static void Reclaim_Free_List() {CXX_DELETE(_Free, _Mpool); _Free = NULL;}
00923
00924 static VN_LDA_ADDR_EXPR *Create(INT32 lda_cr_id);
00925
00926 void free() {_Free->push(this);}
00927 KIND get_kind() const {return LDA_ADDR;}
00928 UINT32 get_num_opnds() const {return 0;}
00929 BOOL has_top_opnd() const {return FALSE;}
00930 BOOL has_bottom_opnd() const {return FALSE;}
00931 IDTYPE get_lda_cr_id_id() const {return _lda_cr_id;}
00932 PTR simplify(VN *) {return this;}
00933 size_t hash() {return (size_t)_lda_cr_id;}
00934
00935 BOOL is_equal_to(CONST_PTR expr) const
00936 {
00937 return (expr != NULL &&
00938 expr->get_kind() == LDA_ADDR &&
00939 expr->get_lda_cr_id() == _lda_cr_id);
00940 }
00941
00942 void print(FILE *fp = stderr) const
00943 {
00944 fprintf(fp, "LDA cr_id(%d)", (INT32)_lda_cr_id);
00945 }
00946
00947 };
00948
00949
00950
00951
00952
00953 class VN_ARRAY_ADDR_EXPR : public VN_EXPR
00954 {
00955 private:
00956
00957 static FREE_STACK *_Free;
00958
00959 WN_ESIZE _esize;
00960 INT32 _num_opnds;
00961 VN_VALNUM _vn[5];
00962 VN_VALNUM *_vn_array;
00963
00964 VN_ARRAY_ADDR_EXPR(WN_ESIZE esize, INT32 num_dims):
00965 _esize(esize)
00966 {
00967 _num_opnds = 1 + 2*num_dims;
00968 if (_num_opnds > 5)
00969 _vn_array = CXX_NEW_ARRAY(VN_VALNUM, _num_opnds, _Mpool);
00970 else
00971 _vn_array = NULL;
00972
00973 for (INT i = 0; i < _num_opnds; i++) set_opnd(i, VN_VALNUM::Bottom());
00974 }
00975
00976 public:
00977
00978 static void Init_Free_List() {_Free = CXX_NEW(FREE_STACK(_Mpool), _Mpool);}
00979 static void Reclaim_Free_List() {CXX_DELETE(_Free, _Mpool); _Free = NULL;}
00980
00981 static VN_ARRAY_ADDR_EXPR *Create(WN_ESIZE esize, INT32 num_dims);
00982
00983 void free()
00984 {
00985 if (_vn_array != NULL)
00986 {
00987 CXX_DELETE_ARRAY(_vn_array, _Mpool);
00988 _vn_array = NULL;
00989 }
00990 _Free->push(this);
00991 }
00992
00993 KIND get_kind() const
00994 {
00995 return ARRAY_ADDR;
00996 }
00997
00998 UINT32 get_num_opnds() const
00999 {
01000 return _num_opnds;
01001 }
01002
01003 VN_VALNUM get_opnd(UINT i=0) const
01004 {
01005 Is_True(i < get_num_opnds(),
01006 ("Erroneous VN_ARRAY_ADDR_EXPR::opnd access"));
01007 return (_vn_array == NULL? _vn[i] : _vn_array[i]);
01008 }
01009
01010 BOOL has_top_opnd() const
01011 {
01012 INT i = 0;
01013 while(i < get_num_opnds() && get_opnd(i) != VN_VALNUM::Top()) i++;
01014 return (i < get_num_opnds());
01015 }
01016
01017 BOOL has_bottom_opnd() const
01018 {
01019 INT i = 0;
01020 while(i < get_num_opnds() && get_opnd(i) != VN_VALNUM::Bottom()) i++;
01021 return (i < get_num_opnds());
01022 }
01023
01024 INT32 get_num_dims() const
01025 {
01026 return (_num_opnds - 1)/2;
01027 }
01028
01029 WN_ESIZE get_esize() const
01030 {
01031 return _esize;
01032 }
01033
01034 void set_opnd(UINT32 i, VN_VALNUM vn)
01035 {
01036 Is_True(i < get_num_opnds(),
01037 ("Erroneous VN_ARRAY_ADDR_EXPR::opnd access"));
01038 if (_vn_array == NULL)
01039 _vn[i] = vn;
01040 else
01041 _vn_array[i] = vn;
01042 }
01043
01044 PTR simplify(VN *v);
01045
01046 size_t hash()
01047 {
01048 size_t hashval = get_opnd(0).ordinal();
01049 Is_True(!has_bottom_opnd() && !has_top_opnd(),
01050 ("Cannot hash() with Top() or Bottom() operand!"));
01051 for (INT i = 1; i < get_num_opnds(); i++)
01052 hashval += (get_opnd(i).ordinal() << 4);
01053 return hashval;
01054 }
01055
01056 BOOL is_equal_to(CONST_PTR expr) const
01057 {
01058 BOOL truth = (expr != NULL &&
01059 expr->get_kind() == ARRAY_ADDR &&
01060 expr->get_esize() == _esize &&
01061 expr->get_num_opnds() == _num_opnds);
01062
01063 for (INT i = 0; truth && i < get_num_opnds(); i++)
01064 truth = (expr->get_opnd(i) == get_opnd(i));
01065 return truth;
01066 }
01067
01068 void print(FILE *fp = stderr) const
01069 {
01070 fprintf(fp, "ARRAY[esize=%d](", (INT32)_esize);
01071 for (INT i = 0; i < get_num_opnds(); i++)
01072 {
01073 if (i > 0)
01074 fputs(",", fp);
01075 get_opnd(i).print(fp);
01076 }
01077 fputs(")", fp);
01078 }
01079
01080 };
01081
01082
01083
01084
01085
01086 class VN_MEMLOC_EXPR : public VN_EXPR
01087 {
01088 private:
01089
01090 static FREE_STACK *_Free;
01091
01092 MTYPE _dsctype;
01093 VN_VALNUM _bytesize;
01094 VN_VALNUM _offset;
01095 VN_VALNUM _base_addr;
01096 VN_VALNUM _vsym_valnum;
01097
01098 VN_MEMLOC_EXPR(MTYPE dsctype,
01099 const VN_VALNUM &bytesize,
01100 const VN_VALNUM &offset,
01101 const VN_VALNUM &base_addr,
01102 const VN_VALNUM &vsym_valnum):
01103 _dsctype(dsctype),
01104 _bytesize(bytesize),
01105 _offset(offset),
01106 _base_addr(base_addr),
01107 _vsym_valnum(vsym_valnum)
01108 {}
01109
01110 void _canonicalize()
01111 {
01112 if (_base_addr < _offset)
01113 Switch_Vn_Opnd(_base_addr, _offset);
01114 }
01115
01116 public:
01117
01118 static void Init_Free_List() {_Free = CXX_NEW(FREE_STACK(_Mpool), _Mpool);}
01119 static void Reclaim_Free_List() {CXX_DELETE(_Free, _Mpool); _Free = NULL;}
01120
01121 static VN_MEMLOC_EXPR *Create(MTYPE dsctype,
01122 const VN_VALNUM &bytesize,
01123 const VN_VALNUM &offset,
01124 const VN_VALNUM &base_addr,
01125 const VN_VALNUM &vsym_valnum);
01126
01127 void free()
01128 {
01129 _Free->push(this);
01130 }
01131
01132 KIND get_kind() const
01133 {
01134 return MEMLOC;
01135 }
01136
01137 UINT32 get_num_opnds() const
01138 {
01139 return 0;
01140 }
01141
01142 BOOL has_top_opnd() const
01143 {
01144 return (_bytesize == VN_VALNUM::Top() ||
01145 _offset == VN_VALNUM::Top() ||
01146 _base_addr == VN_VALNUM::Top() ||
01147 _vsym_valnum == VN_VALNUM::Top());
01148 }
01149
01150 BOOL has_bottom_opnd() const
01151 {
01152 return (_bytesize == VN_VALNUM::Bottom() ||
01153 _offset == VN_VALNUM::Bottom() ||
01154 _base_addr == VN_VALNUM::Bottom() ||
01155 _vsym_valnum == VN_VALNUM::Bottom());
01156 }
01157
01158 MTYPE get_dsctype() const
01159 {
01160 return _dsctype;
01161 }
01162
01163 VN_VALNUM get_bytesize() const
01164 {
01165 return _bytesize;
01166 }
01167
01168 VN_VALNUM get_offset() const
01169 {
01170 return _offset;
01171 }
01172
01173 VN_VALNUM get_base_addr() const
01174 {
01175 return _base_addr;
01176 }
01177
01178 VN_VALNUM get_vsym(UINT i=0) const
01179 {
01180 return _vsym_valnum;
01181 }
01182
01183 PTR simplify(VN *v);
01184
01185 size_t hash()
01186 {
01187 Is_True(!has_bottom_opnd() && !has_top_opnd(),
01188 ("Cannot hash() with Top() or Bottom() operand!"));
01189 _canonicalize();
01190 return (_vsym_valnum.ordinal() +
01191 (_base_addr.ordinal() << 4) +
01192 (_offset.ordinal() << 4) +
01193 (_bytesize.ordinal() << 4) +
01194 (_dsctype << 8));
01195 }
01196
01197 BOOL is_equal_to(CONST_PTR expr) const
01198 {
01199
01200
01201
01202 BOOL truth = (expr != NULL &&
01203 expr->get_kind() == MEMLOC &&
01204 expr->get_dsctype() == _dsctype &&
01205 expr->get_bytesize() == _bytesize &&
01206 expr->get_offset() == _offset &&
01207 expr->get_base_addr() == _base_addr &&
01208 expr->get_vsym() == _vsym_valnum);
01209 return truth;
01210 }
01211
01212 void print(FILE *fp = stderr) const
01213 {
01214 fprintf(fp, "MEMLOC[mty=%s, bytesz=", MTYPE_name(_dsctype));
01215 _bytesize.print(fp);
01216 fputs(", ofst=", fp);
01217 _offset.print(fp);
01218 fputs(", base=", fp);
01219 _base_addr.print(fp);
01220 fputs(", vsym=", fp);
01221 _vsym_valnum.print(fp);
01222 fputs("]", fp);
01223 }
01224
01225 };
01226
01227
01228 #ifdef KEY
01229
01230
01231
01232 class VN_CALL_OP_EXPR : public VN_EXPR
01233 {
01234 private:
01235
01236 static FREE_STACK *_Free;
01237
01238 ST_IDX _aux_id;
01239 UINT32 _num_opnds;
01240 VN_VALNUM_PAIR _opnd[3];
01241 VN_VALNUM_PAIR *_opnd_array;
01242
01243 VN_CALL_OP_EXPR(ST_IDX aux_id,
01244 UINT32 num_opnds):
01245 _aux_id(aux_id), _num_opnds(num_opnds), _opnd_array(NULL)
01246 {
01247 if (num_opnds > 3)
01248 _opnd_array = CXX_NEW_ARRAY(VN_VALNUM_PAIR, num_opnds, _Mpool);
01249 for (INT i = 0; i < num_opnds; i++)
01250 {
01251 set_opnd(i, VN_VALNUM::Bottom());
01252 set_opnd_vsym(i, VN_VALNUM::Bottom());
01253 }
01254 }
01255
01256 public:
01257
01258 static void Init_Free_List() {_Free = CXX_NEW(FREE_STACK(_Mpool), _Mpool);}
01259 static void Reclaim_Free_List() {CXX_DELETE(_Free, _Mpool); _Free = NULL;}
01260
01261 static VN_CALL_OP_EXPR *Create(ST_IDX aux_id,
01262 UINT32 num_opnds);
01263
01264 void free()
01265 {
01266 if (_opnd_array != NULL)
01267 {
01268 CXX_DELETE_ARRAY(_opnd_array, _Mpool);
01269 _opnd_array = NULL;
01270 }
01271 _Free->push(this);
01272 }
01273
01274 KIND get_kind() const
01275 {
01276 return CALL_OP;
01277 }
01278
01279 UINT32 get_num_opnds() const
01280 {
01281 return _num_opnds;
01282 }
01283
01284 VN_VALNUM get_opnd(UINT i) const
01285 {
01286 Is_True(i < get_num_opnds(), ("Erroneous VN_CALL_OP_EXPR::opnd access"));
01287 return (_opnd_array == NULL?
01288 _opnd[i].first : _opnd_array[i].first);
01289 }
01290
01291 VN_VALNUM get_vsym(UINT i=0) const
01292 {
01293 Is_True(i < get_num_opnds(), ("Erroneous VN_CALL_OP_EXPR::vsym access"));
01294 return (_opnd_array == NULL?
01295 _opnd[i].second : _opnd_array[i].second);
01296 }
01297
01298 BOOL has_top_opnd() const
01299 {
01300 INT i = 0;
01301 while(i < get_num_opnds() && get_opnd(i) != VN_VALNUM::Top()) i++;
01302 return (i < get_num_opnds());
01303 }
01304
01305 BOOL has_bottom_opnd() const
01306 {
01307 INT i = 0;
01308 while(i < get_num_opnds() && get_opnd(i) != VN_VALNUM::Bottom()) i++;
01309 return (i < get_num_opnds());
01310 }
01311
01312 ST_IDX get_aux_id() const
01313 {
01314 return _aux_id;
01315 }
01316
01317 void set_opnd(UINT32 i, VN_VALNUM vn)
01318 {
01319 Is_True(i < get_num_opnds(), ("Erroneous VN_CALL_OP_EXPR::opnd access"));
01320 if (_opnd_array == NULL)
01321 _opnd[i].first = vn;
01322 else
01323 _opnd_array[i].first = vn;
01324 }
01325
01326 void set_opnd_vsym(UINT32 i, VN_VALNUM vn)
01327 {
01328 Is_True(i < get_num_opnds(), ("Erroneous VN_CALL_OP_EXPR::vsym access"));
01329 if (_opnd_array == NULL)
01330 _opnd[i].second = vn;
01331 else
01332 _opnd_array[i].second = vn;
01333 }
01334
01335 PTR simplify(VN *v);
01336
01337 size_t hash()
01338 {
01339 size_t hashval = _aux_id;
01340 Is_True(!has_bottom_opnd() && !has_top_opnd(),
01341 ("Cannot hash() with Top() or Bottom() operand!"));
01342 for (INT i = 0; i < get_num_opnds(); i++)
01343 {
01344 hashval += (get_opnd(i).ordinal() << 4);
01345 hashval += (get_vsym(i).ordinal() << 4);
01346 }
01347 return hashval;
01348 }
01349
01350 BOOL is_equal_to(CONST_PTR expr) const
01351 {
01352 BOOL truth = (expr != NULL &&
01353 expr->get_kind() == CALL_OP &&
01354 expr->get_num_opnds() == _num_opnds &&
01355 expr->get_aux_id() == _aux_id);
01356
01357 for (INT i = 0; truth && i < get_num_opnds(); i++)
01358 truth = (expr->get_opnd(i) == get_opnd(i) &&
01359 expr->get_vsym(i) == get_vsym(i));
01360 return truth;
01361 }
01362
01363 void print(FILE *fp = stderr) const
01364 {
01365 fprintf(fp, "%d", _aux_id);
01366 for (INT i = 0; i < get_num_opnds(); i++)
01367 {
01368 if (i > 0)
01369 fputs(", ", fp);
01370 fputs("<", fp);
01371 get_opnd(i).print(fp);
01372 fputs(",", fp);
01373 get_vsym(i).print(fp);
01374 fputs(">", fp);
01375 }
01376 fputs(")", fp);
01377 }
01378
01379 };
01380 #endif
01381
01382 #endif // opt_vn_expr_taxonomyINCLUDED