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 #ifndef opt_points_to_INCLUDED
00041 #define opt_points_to_INCLUDED "opt_points_to.h"
00042
00043 #include "defs.h"
00044 #include "config.h"
00045 #include "opt_defs.h"
00046 #include "cxx_base.h"
00047 #include "cxx_memory.h"
00048 #include "opcode.h"
00049 #include "wn.h"
00050 #include "config_wopt.h"
00051
00052 #include "be_memop_annot.h"
00053 #if defined(TARG_SL)
00054 #include "intrn_info.h"
00055 #endif
00056
00057 typedef struct bs BS;
00058
00059
00060 struct STAB_ADAPTER {
00061 ST *St_ptr (WN *wn) const { return WN_st (wn); }
00062 };
00063
00064 class OPT_STAB;
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 enum EXPR_KIND {
00106 EXPR_IS_INVALID,
00107 EXPR_IS_BEING_PROCESSED,
00108 EXPR_IS_INT,
00109 EXPR_IS_ADDR,
00110 EXPR_IS_UNKNOWN,
00111 EXPR_IS_ANY
00112 };
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 enum BASE_KIND {
00132 BASE_IS_INVALID,
00133 BASE_IS_FIXED,
00134 BASE_IS_DYNAMIC,
00135 BASE_IS_UNKNOWN,
00136
00137 MAX_BASE_KIND
00138 };
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 enum OFST_KIND {
00149 OFST_IS_INVALID,
00150 OFST_IS_FIXED,
00151 OFST_IS_UNKNOWN
00152 };
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 enum PT_ATTR {
00199 PT_ATTR_NONE = 0,
00200 PT_ATTR_NOT_ADDR_SAVED = 0x1,
00201 PT_ATTR_NOT_ADDR_PASSED = 0x2,
00202 PT_ATTR_LOCAL = 0x4,
00203 PT_ATTR_GLOBAL = 0x8,
00204 PT_ATTR_NAMED = 0x10,
00205 PT_ATTR_CONST = 0x20,
00206 PT_ATTR_RESTRICTED = 0x40,
00207 PT_ATTR_UNIQUE_PT = 0x80,
00208 PT_ATTR_F_PARAM = 0x100,
00209 PT_ATTR_DEDICATED = 0x200,
00210
00211 PT_ATTR_NO_ALIAS = 0x400,
00212
00213
00214
00215
00216 PT_ATTR_WEAK = 0x800,
00217 PT_ATTR_WEAK_BASE = 0x1000,
00218 PT_ATTR_IS_POINTER = 0x2000,
00219 PT_ATTR_SAFE_TO_SPECULATE = 0x4000,
00220 PT_ATTR_NOT_AUTO = 0x8000,
00221 PT_ATTR_FORMAL = 0x10000,
00222 PT_ATTR_DEFAULT_VSYM = 0x20000,
00223
00224 PT_ATTR_F90_POINTER = 0x40000,
00225
00226 PT_ATTR_NOT_F90_POINTER = 0x80000,
00227
00228 PT_ATTR_NOT_F90_TARGET = 0x100000,
00229
00230 PT_ATTR_NOT_ALLOCA_MEM = 0x200000,
00231
00232 PT_ATTR_EXTENDED = 0x400000,
00233
00234 PT_ATTR_THIS_PTR = 0x800000,
00235 #ifdef KEY
00236 PT_ATTR_FIELD = 0x1000000,
00237 #endif
00238
00239
00240 };
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 class ALIAS_INFO {
00257
00258 friend class POINTS_TO;
00259 mUINT32 _expr_kind :3;
00260 mUINT32 _base_kind :3;
00261 mUINT32 _ofst_kind :2;
00262 mUINT32 _based_sym_depth:3;
00263 mUINT32 _unused : 5;
00264 mUINT32 _bit_ofst : 8;
00265 mUINT32 _bit_size : 8;
00266
00267
00268
00269
00270
00271
00272
00273 mUINT32 _iofst_kind :2;
00274
00275 mUINT32 _ptr_is_pointer:1;
00276 mUINT32 _ptr_is_aux_id :1;
00277 mUINT32 _ptr_is_coderep_id:1;
00278
00279 PT_ATTR _attr;
00280 INT64 _byte_ofst;
00281 UINT64 _byte_size;
00282 ST *_base;
00283 ST *_based_sym;
00284 union {
00285 ST *_ptr;
00286 AUX_ID _aux_id;
00287 INT32 _coderep_id;
00288 } u;
00289 VER_ID _ptr_ver;
00290 IDTYPE _alias_class;
00291
00292
00293 IDTYPE _ip_alias_class;
00294
00295
00296
00297 };
00298
00299
00300 const IDTYPE OPTIMISTIC_AC_ID = 0;
00301 const IDTYPE PESSIMISTIC_AC_ID = 1;
00302
00303 typedef enum {
00304 AR_INVALID,
00305 AR_NOT_ALIAS,
00306 AR_POSSIBLE_ALIAS,
00307 AR_DEFINITE_ALIAS,
00308
00309
00310 AR_IDENTICAL_BYTES,
00311 AR_IDENTICAL,
00312 } ALIAS_KIND_CODE ;
00313
00314 class ALIAS_KIND {
00315 private:
00316 ALIAS_KIND_CODE _kind;
00317
00318 public:
00319 ALIAS_KIND (void) { _kind = AR_INVALID ; }
00320 ALIAS_KIND (const ALIAS_KIND & ak) { _kind = ak._kind; }
00321 ALIAS_KIND (ALIAS_KIND_CODE kind) { _kind = kind; }
00322
00323 ALIAS_KIND_CODE Alias_kind (void) const { return _kind; }
00324
00325
00326 operator BOOL () const { return _kind != AR_NOT_ALIAS; }
00327
00328 BOOL Definite (void) const {
00329 return _kind == AR_DEFINITE_ALIAS ||
00330 _kind == AR_IDENTICAL_BYTES ||
00331 _kind == AR_IDENTICAL ||
00332 _kind == AR_NOT_ALIAS;
00333 }
00334 };
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 class POINTS_TO {
00346 private:
00347 ALIAS_INFO ai;
00348 TY_IDX _ty;
00349 TY_IDX _hl_ty;
00350 UINT32 _field_id;
00351 INT32 _id;
00352 PT_MEM_ANNOT _mem_annot;
00353
00354
00355
00356
00357 POINTS_TO &operator= (const POINTS_TO &p)
00358 { ai = p.ai; _ty = p._ty; _id = p._id;
00359 _hl_ty = p._hl_ty; _field_id = p._field_id;
00360 _mem_annot = p._mem_annot; return *this; }
00361
00362 POINTS_TO(const POINTS_TO &);
00363
00364 void Clear_Selector (void)
00365 {ai._ptr_is_pointer = ai._ptr_is_aux_id = ai._ptr_is_coderep_id = 0;}
00366 void Set_ptr_is_pointer (void) {
00367 Is_True (((BASE_KIND)ai._base_kind) != BASE_IS_FIXED,
00368 ("It is expected to be indirect load"));
00369 Clear_Selector (); ai._ptr_is_pointer = 1;
00370 }
00371 void Set_ptr_is_aux_id (void) {
00372 Is_True (((BASE_KIND)ai._base_kind) != BASE_IS_FIXED,
00373 ("It is expected to be indirect load"));
00374 Clear_Selector ();ai._ptr_is_aux_id = 1;
00375 }
00376 void Set_ptr_is_coderep_id (void) {
00377 Is_True (((BASE_KIND)ai._base_kind) != BASE_IS_FIXED,
00378 ("It is expected to be indirect load"));
00379 Clear_Selector ();ai._ptr_is_coderep_id=1;
00380 }
00381 void Reset_ptr_is_aux_id (void) { ai._ptr_is_aux_id = 0; }
00382 void Reset_ptr_is_pointer (void){ ai._ptr_is_pointer = 0;}
00383 void Reset_ptr_is_coderep_id (void) {ai._ptr_is_coderep_id=0;}
00384
00385 public:
00386
00387
00388 EXPR_KIND Expr_kind(void) const { return (EXPR_KIND) ai._expr_kind; }
00389 BASE_KIND Base_kind(void) const { return (BASE_KIND) ai._base_kind; }
00390 OFST_KIND Ofst_kind(void) const { return (OFST_KIND) ai._ofst_kind; }
00391 OFST_KIND Iofst_kind(void) const { return (OFST_KIND) ai._iofst_kind; }
00392 ST *Base(void) const { return ai._base; }
00393
00394 BOOL Pointer_is_named_symbol (void) const{ return ai._ptr_is_pointer != 0; }
00395 BOOL Pointer_is_aux_id (void) const { return ai._ptr_is_aux_id != 0; }
00396 BOOL Pointer_is_coderep_id (void) const { return ai._ptr_is_coderep_id != 0;}
00397 ST *Pointer(void) const
00398 { return Pointer_is_named_symbol () ? ai.u._ptr : NULL; }
00399 AUX_ID Pointer_aux_id(void) const
00400 { return Pointer_is_aux_id () ? ai.u._aux_id : 0; }
00401 INT32 Pointer_coderep_id (void) const
00402 { return Pointer_is_coderep_id() ? ai.u._coderep_id : 0; }
00403 VER_ID Pointer_ver (void) const {
00404 return Pointer_is_named_symbol () || Pointer_is_aux_id() ? ai._ptr_ver : 0; }
00405
00406
00407 BOOL Has_annotation (void) const { return _mem_annot.Has_annotation (); }
00408 void Replace_or_add_annot (const MEMOP_ANNOT_ITEM& i)
00409 { _mem_annot.Replace_or_add_annot (i);}
00410 void Replace_or_add_annots (MEMOP_ANNOT* annots)
00411 { _mem_annot.Replace_or_add_annots (annots); }
00412 void Remove_annot (MEM_ANNOT_KIND kind) { _mem_annot.Remove_annot (kind); }
00413 PT_MEM_ANNOT& Mem_annot (void) { return _mem_annot; }
00414 UINT64 Malloc_id (void) const { return _mem_annot.Malloc_id (); }
00415 void Set_malloc_id (UINT64 id) { _mem_annot.Set_malloc_id (id); }
00416 LMV_ALIAS_GROUP LMV_alias_group (void) const
00417 { return _mem_annot.LMV_alias_group (); }
00418 void Set_LMV_alias_group (LMV_ALIAS_GROUP grp_id)
00419 { _mem_annot.Set_LMV_alias_group(grp_id);}
00420
00421
00422 #if _NO_BIT_FIELDS
00423 mINT64 Ofst(void) const { return ai._ofst; }
00424 mINT64 Size(void) const { return ai._size; }
00425 #else
00426 mINT64 Byte_Ofst(void) const { return ai._byte_ofst; }
00427 mINT64 Byte_Size(void) const { return ai._byte_size; }
00428 mUINT8 Bit_Ofst(void) const { return ai._bit_ofst; }
00429 mUINT8 Bit_Size(void) const { return ai._bit_size; }
00430 #endif
00431 ST *Based_sym(void) const { return ai._based_sym; }
00432 UINT32 Based_sym_depth(void) const { return ai._based_sym_depth; }
00433 TY_IDX Ty(void) const { return _ty; }
00434 TY_IDX Highlevel_Ty (void) const { return _hl_ty; }
00435 UINT32 Field_id (void) const { return _field_id; }
00436 INT32 Id(void) const { return _id; }
00437 PT_ATTR Attr(void) const { return ai._attr; }
00438 BOOL Not_addr_saved(void) const { return ai._attr & PT_ATTR_NOT_ADDR_SAVED; }
00439 BOOL Not_addr_passed(void) const { return ai._attr & PT_ATTR_NOT_ADDR_PASSED; }
00440 BOOL Local(void) const { return ai._attr & PT_ATTR_LOCAL; }
00441 BOOL Global(void) const { return ai._attr & PT_ATTR_GLOBAL; }
00442 BOOL Named(void) const { return ai._attr & PT_ATTR_NAMED; }
00443 BOOL Unnamed(void) const { return !Named(); }
00444 BOOL Const(void) const { return ai._attr & PT_ATTR_CONST; }
00445 BOOL Restricted(void) const { return ai._attr & PT_ATTR_RESTRICTED; }
00446 BOOL This_ptr(void) const { return ai._attr & PT_ATTR_THIS_PTR; }
00447 BOOL Unique_pt(void) const { return ai._attr & PT_ATTR_UNIQUE_PT; }
00448 BOOL F_param(void) const { return ai._attr & PT_ATTR_F_PARAM; }
00449 BOOL Dedicated(void) const { return ai._attr & PT_ATTR_DEDICATED; }
00450 BOOL No_alias(void) const { return ai._attr & PT_ATTR_NO_ALIAS; }
00451 BOOL Weak(void) const { return ai._attr & PT_ATTR_WEAK; }
00452 BOOL Weak_base(void) const { return ai._attr & PT_ATTR_WEAK_BASE; }
00453 BOOL Is_pointer(void) const { return ai._attr & PT_ATTR_IS_POINTER; }
00454 BOOL Safe_to_speculate(void) const { return ai._attr & PT_ATTR_SAFE_TO_SPECULATE; }
00455 BOOL Not_auto(void) const { return ai._attr & PT_ATTR_NOT_AUTO; }
00456 BOOL Formal(void) const { return ai._attr & PT_ATTR_FORMAL; }
00457 BOOL Default_vsym(void) const { return ai._attr & PT_ATTR_DEFAULT_VSYM; }
00458 BOOL Known_f90_pointer(void) const
00459 { return ai._attr & PT_ATTR_F90_POINTER; }
00460 BOOL Known_not_f90_pointer(void) const
00461 { return ai._attr & PT_ATTR_NOT_F90_POINTER; }
00462 BOOL Not_f90_target(void) const { return ai._attr & PT_ATTR_NOT_F90_TARGET; }
00463 BOOL Not_alloca_mem(void) const { return ai._attr & PT_ATTR_NOT_ALLOCA_MEM; }
00464 BOOL Extended(void) const { return ai._attr & PT_ATTR_EXTENDED; }
00465 #ifdef KEY
00466 BOOL Is_field(void) const { return ai._attr & PT_ATTR_FIELD; }
00467 #endif
00468
00469
00470
00471
00472 void Set_expr_kind(EXPR_KIND expr_kind) { ai._expr_kind = expr_kind; }
00473 void Set_base_kind(BASE_KIND base_kind) { ai._base_kind = base_kind; }
00474 void Set_ofst_kind(OFST_KIND ofst_kind) { ai._ofst_kind = ofst_kind; }
00475 void Set_iofst_kind(OFST_KIND iofst_kind) { ai._iofst_kind = iofst_kind; }
00476 void Set_unused() { ai._unused = 0; }
00477 void Set_base(ST *base) { ai._base = base; }
00478 void Set_byte_ofst(mINT64 ofst) { ai._byte_ofst = ofst; }
00479 void Set_byte_size(mINT64 size) { ai._byte_size = size; }
00480 void Set_bit_ofst_size(mUINT8 ofst, mUINT8 size) {
00481 ai._bit_ofst = ofst;
00482 ai._bit_size = size;
00483 }
00484
00485 void Set_pointer (ST* ptr) {Set_ptr_is_pointer(); ai.u._ptr = ptr; }
00486 void Set_pointer_as_aux_id (AUX_ID id) {Set_ptr_is_aux_id(); ai.u._aux_id = id;}
00487 void Set_pointer_as_coderep_id (INT32 id) {
00488 Set_ptr_is_coderep_id (); ai.u._coderep_id = id;
00489 }
00490 void Set_pointer_ver (VER_ID ver) {
00491 Is_True (!Pointer_is_coderep_id (),
00492 ("The version does not make sense for coderep"));
00493 ai._ptr_ver = ver;
00494 }
00495
00496 void Set_based_sym(ST *sym) { ai._based_sym = sym; }
00497 void Set_based_sym_depth(UINT32 d) { ai._based_sym_depth = (d > 7) ? 7 : d; }
00498 void Set_alias_class(const IDTYPE alias_class)
00499 {
00500 if (alias_class <= WOPT_Alias_Class_Limit) {
00501 ai._alias_class = alias_class;
00502 }
00503 else {
00504 ai._alias_class = PESSIMISTIC_AC_ID;
00505 }
00506 }
00507 void Set_ip_alias_class(const IDTYPE iac)
00508 {
00509 if (iac <= WOPT_Ip_Alias_Class_Limit) {
00510 ai._ip_alias_class = iac;
00511 }
00512 else {
00513 ai._ip_alias_class = PESSIMISTIC_AC_ID;
00514 }
00515 }
00516 void Set_ty(TY_IDX ty) { _ty = ty; }
00517 void Set_hl_ty(TY_IDX hlty) { _hl_ty = hlty; }
00518 void Set_field_id (UINT32 fldid) { _field_id = fldid; }
00519 void Set_id(INT32 id) { _id = id; }
00520 void Set_attr(PT_ATTR attr) { ai._attr = attr; }
00521 void Set_not_addr_saved(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_NOT_ADDR_SAVED); }
00522 void Set_not_addr_passed(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_NOT_ADDR_PASSED); }
00523 void Set_local(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_LOCAL); }
00524 void Set_global(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_GLOBAL); }
00525 void Set_named(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_NAMED); }
00526 void Set_const(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_CONST); }
00527 void Set_restricted(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_RESTRICTED); }
00528 void Set_unique_pt(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_UNIQUE_PT); }
00529 void Set_F_param(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_F_PARAM); }
00530 void Set_dedicated(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_DEDICATED); }
00531 void Set_no_alias(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_NO_ALIAS); }
00532 void Set_weak(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_WEAK); }
00533 void Set_weak_base(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_WEAK_BASE); }
00534 void Set_is_pointer(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_IS_POINTER); }
00535 void Set_safe_to_speculate(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_SAFE_TO_SPECULATE); }
00536 void Set_not_auto(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_NOT_AUTO); }
00537 void Set_formal(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_FORMAL); }
00538 void Set_default_vsym(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_DEFAULT_VSYM); }
00539 void Set_known_f90_pointer(void)
00540 {
00541 Is_True(!Known_not_f90_pointer(),
00542 ("POINTS_TO: f90_pointer attributes inconsistent"));
00543 ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_F90_POINTER);
00544 }
00545 void Set_known_not_f90_pointer(void)
00546 {
00547 Is_True(!Known_f90_pointer(),
00548 ("POINTS_TO: f90_pointer attributes inconsistent"));
00549 ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_NOT_F90_POINTER);
00550 }
00551 void Set_not_f90_target(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_NOT_F90_TARGET); }
00552 void Set_not_alloca_mem(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_NOT_ALLOCA_MEM); }
00553 void Set_extended(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_EXTENDED); }
00554 #ifdef KEY
00555 void Set_is_field(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_FIELD); }
00556 #endif
00557
00558 void Reset_attr(void) { ai._attr = PT_ATTR_NONE; }
00559 void Reset_not_addr_saved(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_NOT_ADDR_SAVED); }
00560 void Reset_not_addr_passed(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_NOT_ADDR_PASSED); }
00561 void Reset_local(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_LOCAL); }
00562 void Reset_global(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_GLOBAL); }
00563 void Reset_named(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_NAMED); }
00564 void Reset_const(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_CONST); }
00565 void Reset_restricted(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_RESTRICTED); }
00566 void Reset_unique_pt(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_UNIQUE_PT); }
00567 void Reset_F_param(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_F_PARAM); }
00568 void Reset_dedicated(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_DEDICATED); }
00569 void Reset_no_alias(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_NO_ALIAS); }
00570 void Reset_weak(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_WEAK); }
00571 void Reset_weak_base(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_WEAK_BASE); }
00572 void Reset_is_pointer(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_IS_POINTER); }
00573 void Reset_safe_to_speculate(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_SAFE_TO_SPECULATE); }
00574 void Reset_not_auto(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_NOT_AUTO); }
00575 void Reset_formal(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_FORMAL); }
00576 void Reset_default_vsym(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_DEFAULT_VSYM); }
00577 void Reset_known_f90_pointer(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_F90_POINTER); }
00578 void Reset_known_not_f90_pointer(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_NOT_F90_POINTER); }
00579 void Reset_not_f90_target(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_NOT_F90_TARGET); }
00580 void Reset_not_alloca_mem(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_NOT_ALLOCA_MEM); }
00581 void Reset_extended(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_EXTENDED); }
00582
00583 void Invalidate_ptr_info (void) {
00584 Clear_Selector ();
00585 ai.u._ptr = NULL; ai._iofst_kind = OFST_IS_INVALID; ai._ptr_ver = (VER_ID)0;
00586 }
00587 #ifdef KEY
00588 void Reset_is_field(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_FIELD); }
00589 #endif
00590
00591 void Init(void) {
00592
00593 Set_expr_kind(EXPR_IS_INVALID);
00594 Set_base_kind(BASE_IS_INVALID);
00595 Set_ofst_kind(OFST_IS_INVALID);
00596 Set_iofst_kind(OFST_IS_INVALID);
00597 Set_unused();
00598 Set_based_sym_depth(0);
00599 Set_base((ST*)NULL);
00600 Invalidate_ptr_info ();
00601 Set_byte_ofst(0);
00602 Set_byte_size(0);
00603 Set_bit_ofst_size(0,0);
00604 Set_based_sym((ST*)NULL);
00605 Set_ty(0);
00606 Set_hl_ty(0);
00607 Set_field_id(0);
00608 Set_id(0);
00609 Set_alias_class(OPTIMISTIC_AC_ID);
00610 Set_ip_alias_class(OPTIMISTIC_AC_ID);
00611 _mem_annot.Init();
00612
00613 Set_attr(PT_ATTR_NONE);
00614 }
00615
00616 #if defined(TARG_SL)
00617 ST* Get_ST_base(ST* st) const;
00618 #endif
00619
00620 BOOL Same_base(const POINTS_TO *) const;
00621
00622
00623 BOOL Same_pointer (const POINTS_TO*) const;
00624
00625
00626 BOOL Pointer_info_does_help (void) const;
00627
00628
00629 BOOL Different_base(const POINTS_TO *) const;
00630
00631
00632 ALIAS_KIND Overlap(const POINTS_TO *) const;
00633
00634
00635
00636 BOOL Similar(const POINTS_TO *pt) const {
00637 if (Expr_kind() == pt->Expr_kind() &&
00638 Base_kind() == pt->Base_kind() &&
00639 Ofst_kind() == pt->Ofst_kind() &&
00640 Base_kind() == BASE_IS_FIXED &&
00641 Ofst_kind() == OFST_IS_FIXED &&
00642 Base() == pt->Base() &&
00643 Byte_Ofst() == pt->Byte_Ofst() &&
00644 Byte_Size() == pt->Byte_Size())
00645 return TRUE;
00646
00647 if ((F_param() && pt->F_param()) &&
00648 (Based_sym() == pt->Based_sym()))
00649 return TRUE;
00650
00651 return FALSE;
00652 }
00653
00654 IDTYPE Alias_class(void) const { return ai._alias_class; }
00655
00656 IDTYPE Ip_alias_class(void) const { return ai._ip_alias_class; }
00657
00658 void Shift_ofst(mINT64 shift)
00659 { Set_byte_ofst( Byte_Ofst() + shift ); }
00660
00661
00662 BOOL Base_is_fixed(void) const
00663 { return Base_kind() == BASE_IS_FIXED; }
00664
00665 BOOL Int_is_constant(void) const
00666 { return (Ofst_kind() == OFST_IS_FIXED); }
00667
00668 mINT64 Int_const_val(void) const
00669 { return Byte_Ofst(); }
00670
00671 void Set_const_val(mINT64 val)
00672 { Set_byte_ofst(val); Set_ofst_kind(OFST_IS_FIXED); }
00673
00674
00675 void Meet_info_from_alias_class(const POINTS_TO *);
00676
00677
00678 void Meet(const POINTS_TO *, ST *);
00679
00680
00681 void Copy_fully(const POINTS_TO *p)
00682 { *this = *p; }
00683
00684 void Copy_fully(const POINTS_TO &p)
00685 { *this = p; }
00686
00687
00688
00689 void Copy_non_sticky_info(const POINTS_TO *p)
00690 {
00691 BOOL is_unique_pt = Unique_pt();
00692 BOOL is_restricted = Restricted();
00693 ST *based_sym = Based_sym();
00694 PT_MEM_ANNOT mem_annot = Mem_annot();
00695
00696 *this = *p;
00697 if (is_unique_pt) {
00698 Set_unique_pt();
00699 Set_based_sym(based_sym);
00700 }
00701 if (is_restricted) {
00702 Set_restricted();
00703 Set_based_sym(based_sym);
00704 }
00705 _mem_annot = mem_annot;
00706 }
00707
00708 void Copy_pointer_info (const POINTS_TO* p)
00709 {
00710 Clear_Selector ();
00711 if (p->Pointer_is_named_symbol()) {
00712 Set_pointer (p->Pointer ());
00713 Set_pointer_ver (p->Pointer_ver());
00714 } else if (p->Pointer_is_aux_id()) {
00715 Set_pointer_as_aux_id (p->Pointer_aux_id ());
00716 Set_pointer_ver (p->Pointer_ver());
00717 } else if (p->Pointer_is_coderep_id ()) {
00718 Set_pointer_as_coderep_id (p->Pointer_coderep_id());
00719 }
00720 }
00721
00722
00723 void Copy_indirect_access_info (const POINTS_TO* p)
00724 {
00725 Copy_pointer_info (p);
00726 Set_iofst_kind (p->Iofst_kind ());
00727 Set_byte_size (p->Byte_Size ());
00728 Set_bit_ofst_size (p->Bit_Ofst (), p->Bit_Size ());
00729 }
00730
00731
00732
00733 void Copy_non_sticky_info(const POINTS_TO &p)
00734 {
00735 BOOL is_unique_pt = Unique_pt();
00736 BOOL is_restricted = Restricted();
00737 ST *based_sym = Based_sym();
00738 *this = p;
00739 if (is_unique_pt) {
00740 Set_unique_pt();
00741 Set_based_sym(based_sym);
00742 }
00743 if (is_restricted) {
00744 Set_restricted();
00745 Set_based_sym(based_sym);
00746 }
00747 }
00748
00749
00750 void Analyze_ST(ST *st, INT64 byte_ofst, INT64 byte_size, UINT8 bit_ofst,
00751 UINT8 bit_size, TY_IDX ty, BOOL has_equiv);
00752
00753 void Analyze_ST_as_base(ST *, INT64, TY_IDX);
00754
00755 void Analyze_WN_expr(WN *);
00756
00757 #ifdef __cplusplus
00758 template <class SYMTAB> void Analyze_Ldid_Base(WN *wn, const SYMTAB &symtab);
00759 template <class SYMTAB> void Analyze_Parameter_Base(WN *wn, const SYMTAB &symtab);
00760 template <class SYMTAB> void Analyze_WN_expr(WN *wn, const SYMTAB &symtab);
00761 #endif
00762
00763 void Analyze_Lda_Base(WN *, const OPT_STAB &);
00764 void Analyze_Lda_Base(WN *, const STAB_ADAPTER &);
00765 void Lower_to_base(WN *);
00766
00767 POINTS_TO() {}
00768 POINTS_TO(ST *st, BOOL indirect = FALSE) {
00769 Init();
00770 if (indirect)
00771 Analyze_ST_as_base(st, 0, 0);
00772 else
00773 Analyze_ST(st, 0, ST_size(st), 0, 0, 0, TRUE);
00774 if (Byte_Size() == 0)
00775 Set_ofst_kind(OFST_IS_UNKNOWN);
00776 }
00777 POINTS_TO(ST *st, INT64 ofst, INT64 size, BOOL indirect = FALSE) {
00778 Init();
00779 if (indirect)
00780 Analyze_ST_as_base(st, ofst, 0);
00781 else
00782 Analyze_ST(st, ofst, size, 0, 0, 0, TRUE);
00783 if (Byte_Size() == 0)
00784 Set_ofst_kind(OFST_IS_UNKNOWN);
00785 }
00786 POINTS_TO(ST* st, INT64 byte_ofst, INT64 byte_size, UINT8 bit_ofst,
00787 UINT8 bit_size, BOOL indirect = FALSE) {
00788 Init();
00789 if (indirect)
00790 Analyze_ST_as_base(st, byte_ofst, 0);
00791 else
00792 Analyze_ST(st, byte_ofst, byte_size, bit_ofst, bit_size, 0, TRUE);
00793 if (Byte_Size() == 0)
00794 Set_ofst_kind(OFST_IS_UNKNOWN);
00795 }
00796
00797
00798 void Print(FILE *fp=stderr) const;
00799 };
00800
00801 class PT_MEMOP_ANNOT_STIKER {
00802 private:
00803 BOOL _has_annot;
00804 POINTS_TO* _pt;
00805 PT_MEM_ANNOT _mem_annot;
00806
00807 public:
00808 PT_MEMOP_ANNOT_STIKER (POINTS_TO* pt) {
00809 if (_has_annot = pt->Has_annotation()) {
00810 _mem_annot = pt->Mem_annot () ;
00811 _pt = pt;
00812 }
00813 }
00814
00815 ~PT_MEMOP_ANNOT_STIKER (void) {
00816 if (_has_annot) {
00817 if (_mem_annot.Item_is_inlined ())
00818 _pt->Replace_or_add_annot (_mem_annot.Get_inlined_item ());
00819 else
00820 _pt->Replace_or_add_annots (_mem_annot.Get_annots_ptr ());
00821 }
00822 }
00823 };
00824
00825
00826
00827 class POINTS_TO_NODE : public SLIST_NODE {
00828 DECLARE_SLIST_NODE_CLASS(POINTS_TO_NODE)
00829 private:
00830 POINTS_TO *_pt;
00831 POINTS_TO_NODE(void);
00832 POINTS_TO_NODE(const POINTS_TO_NODE&);
00833 POINTS_TO_NODE& operator = (const POINTS_TO_NODE&);
00834 public:
00835 POINTS_TO_NODE(POINTS_TO *pt) { _pt = pt; }
00836 ~POINTS_TO_NODE(void) {}
00837 POINTS_TO *Pt(void) const { return _pt; }
00838 };
00839
00840
00841
00842
00843 class POINTS_TO_LIST : public SLIST {
00844 DECLARE_SLIST_CLASS (POINTS_TO_LIST, POINTS_TO_NODE)
00845 private:
00846 POINTS_TO_LIST(const POINTS_TO_LIST&);
00847 POINTS_TO_LIST& operator = (const POINTS_TO_LIST&);
00848 public:
00849 void Prepend( POINTS_TO *pt, MEM_POOL *pool );
00850 };
00851
00852
00853 class POINTS_TO_ITER : public SLIST_ITER {
00854 private:
00855 DECLARE_SLIST_ITER_CLASS (POINTS_TO_ITER, POINTS_TO_NODE, POINTS_TO_LIST)
00856 POINTS_TO_ITER(const POINTS_TO_ITER&);
00857 POINTS_TO_ITER& operator = (const POINTS_TO_ITER&);
00858 public:
00859 ~POINTS_TO_ITER(void) {}
00860 POINTS_TO_NODE *First_elem(void) { return First(); }
00861 POINTS_TO_NODE *Next_elem(void) { return Next(); }
00862 };
00863
00864
00865 #ifdef Is_True_On
00866 extern void CHECK_POINTS_TO(POINTS_TO *);
00867 #else
00868 #define CHECK_POINTS_TO(pt)
00869 #endif
00870
00871
00872 void Expand_ST_into_base_and_ofst(ST *st, INT64 st_ofst, ST ** base, INT64 *ofst);
00873
00874 template <class SYMTAB> WN *Find_addr_recur(WN *, const SYMTAB &);
00875
00876 inline static BOOL Is_FORTRAN()
00877 {
00878 const PU& pu = Get_Current_PU ();
00879 return (PU_f77_lang (pu) || PU_f90_lang (pu));
00880 }
00881
00882 template <class SYMTAB>
00883 ST *Is_nested_call(const WN *wn, const SYMTAB &symtab);
00884
00885 extern ST *Is_nested_call(const WN *wn);
00886
00887
00888
00889
00890
00891 template <class SYMTAB>
00892 void POINTS_TO::Analyze_Ldid_Base(WN *wn_ldid, const SYMTAB &stab)
00893 {
00894 ST *st = stab.St_ptr(wn_ldid);
00895 INT64 ofst = WN_offset(wn_ldid);
00896 TY_IDX ty = WN_ty(wn_ldid);
00897 Analyze_ST_as_base(st, ofst, ty);
00898 Set_ofst_kind(OFST_IS_UNKNOWN);
00899 }
00900
00901
00902 template <class SYMTAB>
00903 WN *Find_addr_recur(WN *wn, const SYMTAB &stab)
00904 {
00905 if (wn == NULL) return NULL;
00906 switch (WN_operator(wn)) {
00907 #if defined(TARG_SL)
00908 case OPR_INTRINSIC_OP:
00909 if(INTRN_copy_addr(WN_intrinsic(wn)))
00910 return Find_addr_recur(WN_kid0(WN_kid0(wn)),stab);
00911 return NULL;
00912
00913 case OPR_PARM:
00914 if ((WN_Parm_By_Reference(wn) || WN_Parm_Dereference(wn)) && WN_kid_count(wn))
00915 return Find_addr_recur(WN_kid0(wn), stab);
00916
00917 return NULL;
00918
00919 #else
00920
00921 if (WN_Parm_By_Reference(wn) && WN_kid_count(wn))
00922 return Find_addr_recur(WN_kid0(wn), stab);
00923
00924 return NULL;
00925 #endif
00926 case OPR_LDA:
00927 return wn;
00928 case OPR_LDID:
00929 {
00930 ST *st = stab.St_ptr(wn);
00931 if (Is_FORTRAN() && ST_sclass(st) == SCLASS_FORMAL &&
00932 ! ST_is_value_parm(st))
00933 return wn;
00934 if (ST_pt_to_unique_mem(st)) {
00935 TY_IDX ty = WN_ty(wn);
00936 if (TY_kind(Ty_Table[ty]) != KIND_POINTER) {
00937 TY_IDX new_ty = Make_Pointer_Type(ty);
00938 WN_set_ty(wn, new_ty);
00939
00940 DevWarn("Fixing TY %s of LDID <%s> to a pointer type because the ST has PT_TO_UNIQUE_MEM set",
00941 TY_name(ty) ? TY_name(ty) : "noname",
00942 ST_name(st) ? ST_name(st) : "noname");
00943 }
00944 return wn;
00945 }
00946 TY_IDX ty = WN_ty(wn);
00947 if (TY_kind(Ty_Table[ty]) == KIND_POINTER)
00948 return wn;
00949 Is_True(!TY_is_restrict(ty),
00950 ("__restrict object must be KIND_POINTER"));
00951 return NULL;
00952 }
00953 case OPR_ARRAY:
00954 return Find_addr_recur(WN_kid0(wn), stab);
00955 case OPR_ADD:
00956 {
00957 WN *ret_wn;
00958 for (INT32 i = 0; i < WN_kid_count(wn); i++)
00959 if ((ret_wn = Find_addr_recur(WN_kid(wn,i), stab)) != NULL)
00960 return ret_wn;
00961 return NULL;
00962 }
00963 case OPR_SUB:
00964 return Find_addr_recur(WN_kid(wn,0), stab);
00965 default:
00966 return NULL;
00967 }
00968 }
00969
00970
00971 template <class SYMTAB>
00972 void POINTS_TO::Analyze_Parameter_Base(WN *wn, const SYMTAB &stab)
00973 {
00974 Set_expr_kind(EXPR_IS_ADDR);
00975 Set_base_kind(BASE_IS_UNKNOWN);
00976 Set_ofst_kind(OFST_IS_UNKNOWN);
00977 WN *wn_lda;
00978 switch (WN_operator(wn)) {
00979 case OPR_LDA:
00980 Analyze_Lda_Base(wn, stab);
00981 Lower_to_base(NULL);
00982 break;
00983 case OPR_LDID:
00984 Analyze_Ldid_Base(wn, stab);
00985 Set_ofst_kind(OFST_IS_UNKNOWN);
00986 break;
00987
00988 case OPR_ARRAY:
00989 default:
00990 wn_lda = Find_addr_recur(wn, stab);
00991 if (wn_lda != NULL) {
00992 if (WN_operator(wn_lda) == OPR_LDA) {
00993 Analyze_Lda_Base(wn_lda, stab);
00994 Lower_to_base(NULL);
00995 } else if (WN_operator(wn_lda) == OPR_LDID) {
00996 Analyze_Ldid_Base(wn_lda, stab);
00997 Lower_to_base(NULL);
00998
00999 }
01000 }
01001 break;
01002 }
01003 }
01004
01005
01006 template <class SYMTAB>
01007 void POINTS_TO::Analyze_WN_expr(WN *wn, const SYMTAB &stab)
01008 {
01009 OPERATOR opr = WN_operator(wn);
01010 switch ( opr ) {
01011 case OPR_LDID:
01012 case OPR_STID:
01013 case OPR_LDBITS:
01014 case OPR_STBITS:
01015 {
01016 ST *st = stab.St_ptr(wn);
01017 if (ST_sclass(st) != SCLASS_UNKNOWN) {
01018 TY_IDX ty = ST_type(st);
01019 INT64 ofst = WN_offset(wn);
01020 INT64 size = MTYPE_size_min(WN_desc(wn)) >> 3;
01021 if (opr == OPR_LDBITS || opr == OPR_STBITS)
01022 Analyze_ST (st, ofst, size, WN_bit_offset (wn), WN_bit_size
01023 (wn), ty, TRUE );
01024 else
01025 Analyze_ST(st, ofst, size, 0, 0, ty, TRUE );
01026 return;
01027 }
01028 }
01029 break;
01030 case OPR_ILDBITS:
01031 case OPR_ISTBITS:
01032 case OPR_ILOAD:
01033 case OPR_MLOAD:
01034 case OPR_PARM:
01035 case OPR_ISTORE:
01036 case OPR_MSTORE:
01037 {
01038 WN *wn_lda = Find_addr_recur(
01039 OPERATOR_is_store(opr) ? WN_kid1(wn) : WN_kid0(wn), stab);
01040 if (wn_lda != NULL) {
01041 if (WN_operator(wn_lda) == OPR_LDA) {
01042 ST *st = stab.St_ptr(wn_lda);
01043 if (ST_sclass(st) != SCLASS_UNKNOWN) {
01044 Analyze_Lda_Base(wn_lda, stab);
01045 Lower_to_base(NULL);
01046 return;
01047 }
01048 } else if (WN_operator(wn_lda) == OPR_LDID) {
01049 Analyze_Ldid_Base(wn_lda, stab);
01050 Lower_to_base(NULL);
01051 return;
01052 }
01053 }
01054 }
01055 break;
01056 default:
01057 break;
01058 }
01059 Init();
01060 }
01061
01062
01063
01064
01065 template <class SYMTAB>
01066 ST *Is_nested_call(const WN *wn, const SYMTAB &symtab)
01067 {
01068 ST *call_st = NULL;
01069 INT32 num_parms = WN_kid_count(wn);
01070 OPERATOR opr = WN_operator(wn);
01071 if (opr == OPR_CALL) {
01072 call_st = WN_st(wn);
01073 } else if (opr == OPR_ICALL)
01074 num_parms--;
01075
01076
01077
01078
01079
01080
01081 ST *nested_func = NULL;
01082
01083 for ( INT parmkid = 0; parmkid < num_parms; parmkid++ ) {
01084 WN *parm = WN_kid(wn, parmkid);
01085 if ( WN_operator(parm) == OPR_PARM ) {
01086 WN *actual_parm = WN_kid0(parm);
01087 if ( WN_operator(actual_parm) == OPR_LDA ) {
01088
01089
01090
01091
01092
01093 ST *lda_st = symtab.St_ptr(actual_parm);
01094 if ( ST_class(lda_st) == CLASS_FUNC &&
01095 PU_is_nested_func (Pu_Table[ST_pu (lda_st)])
01096 )
01097 nested_func = lda_st;
01098 }
01099 }
01100 }
01101
01102 if ( nested_func == NULL && call_st != NULL &&
01103 PU_is_nested_func (Pu_Table[ST_pu (call_st)])
01104 )
01105 nested_func = call_st;
01106
01107 return nested_func;
01108 }
01109
01110 #endif // opt_points_to_INCLUDED