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 #ifndef opt_points_to_INCLUDED
00037 #define opt_points_to_INCLUDED "opt_points_to.h"
00038
00039 #include "defs.h"
00040 #include "config.h"
00041 #include "cxx_base.h"
00042 #include "cxx_memory.h"
00043 #include "opcode.h"
00044 #include "wn.h"
00045 #include "config_wopt.h"
00046
00047
00048
00049 typedef struct bs BS;
00050
00051
00052 struct STAB_ADAPTER {
00053 ST *St_ptr (WN *wn) const { return WN_st (wn); }
00054 };
00055
00056 class OPT_STAB;
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 enum EXPR_KIND {
00098 EXPR_IS_INVALID,
00099 EXPR_IS_BEING_PROCESSED,
00100 EXPR_IS_INT,
00101 EXPR_IS_ADDR,
00102 EXPR_IS_UNKNOWN,
00103 EXPR_IS_ANY
00104 };
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 enum BASE_KIND {
00124 BASE_IS_INVALID,
00125 BASE_IS_FIXED,
00126 BASE_IS_DYNAMIC,
00127 BASE_IS_UNKNOWN,
00128
00129 MAX_BASE_KIND
00130 };
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 enum OFST_KIND {
00141 OFST_IS_INVALID,
00142 OFST_IS_FIXED,
00143 OFST_IS_UNKNOWN
00144 };
00145
00146
00147
00148
00149
00150
00151
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 enum PT_ATTR {
00191 PT_ATTR_NONE = 0,
00192 PT_ATTR_NOT_ADDR_SAVED = 0x1,
00193 PT_ATTR_NOT_ADDR_PASSED = 0x2,
00194 PT_ATTR_LOCAL = 0x4,
00195 PT_ATTR_GLOBAL = 0x8,
00196 PT_ATTR_NAMED = 0x10,
00197 PT_ATTR_CONST = 0x20,
00198 PT_ATTR_RESTRICTED = 0x40,
00199 PT_ATTR_UNIQUE_PT = 0x80,
00200 PT_ATTR_F_PARAM = 0x100,
00201 PT_ATTR_DEDICATED = 0x200,
00202
00203 PT_ATTR_NO_ALIAS = 0x400,
00204
00205
00206
00207
00208 PT_ATTR_WEAK = 0x800,
00209 PT_ATTR_WEAK_BASE = 0x1000,
00210 PT_ATTR_IS_POINTER = 0x2000,
00211 PT_ATTR_SAFE_TO_SPECULATE = 0x4000,
00212 PT_ATTR_NOT_AUTO = 0x8000,
00213 PT_ATTR_FORMAL = 0x10000,
00214 PT_ATTR_DEFAULT_VSYM = 0x20000,
00215
00216 PT_ATTR_F90_POINTER = 0x40000,
00217
00218 PT_ATTR_NOT_F90_POINTER = 0x80000,
00219
00220 PT_ATTR_NOT_F90_TARGET = 0x100000,
00221
00222 PT_ATTR_NOT_ALLOCA_MEM = 0x200000,
00223
00224 PT_ATTR_EXTENDED = 0x400000
00225
00226
00227 };
00228
00229
00230
00231
00232 class ALIAS_INFO {
00233
00234 friend class POINTS_TO;
00235 mUINT32 _expr_kind :3;
00236 mUINT32 _base_kind :3;
00237 mUINT32 _ofst_kind :2;
00238 mUINT32 _based_sym_depth:3;
00239 mUINT32 _unused : 5;
00240 mUINT32 _bit_ofst : 8;
00241 mUINT32 _bit_size : 8;
00242
00243
00244
00245
00246
00247
00248
00249 PT_ATTR _attr;
00250 INT64 _byte_ofst;
00251 UINT64 _byte_size;
00252 ST *_base;
00253 ST *_based_sym;
00254 IDTYPE _alias_class;
00255
00256
00257 IDTYPE _ip_alias_class;
00258
00259
00260 };
00261
00262
00263
00264 const IDTYPE OPTIMISTIC_AC_ID = 0;
00265 const IDTYPE PESSIMISTIC_AC_ID = 1;
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 class POINTS_TO {
00278 private:
00279 ALIAS_INFO ai;
00280 TY_IDX _ty;
00281 INT32 _id;
00282
00283
00284
00285
00286 POINTS_TO &operator= (const POINTS_TO &p)
00287 { ai = p.ai; _ty = p._ty; _id = p._id; return *this; }
00288
00289 POINTS_TO(const POINTS_TO &);
00290
00291 public:
00292
00293
00294 EXPR_KIND Expr_kind(void) const { return (EXPR_KIND) ai._expr_kind; }
00295 BASE_KIND Base_kind(void) const { return (BASE_KIND) ai._base_kind; }
00296 OFST_KIND Ofst_kind(void) const { return (OFST_KIND) ai._ofst_kind; }
00297 ST *Base(void) const { return ai._base; }
00298 #if _NO_BIT_FIELDS
00299 mINT64 Ofst(void) const { return ai._ofst; }
00300 mINT64 Size(void) const { return ai._size; }
00301 #else
00302 mINT64 Byte_Ofst(void) const { return ai._byte_ofst; }
00303 mINT64 Byte_Size(void) const { return ai._byte_size; }
00304 mUINT8 Bit_Ofst(void) const { return ai._bit_ofst; }
00305 mUINT8 Bit_Size(void) const { return ai._bit_size; }
00306 #endif
00307 ST *Based_sym(void) const { return ai._based_sym; }
00308 UINT32 Based_sym_depth(void) const { return ai._based_sym_depth; }
00309 TY_IDX Ty(void) const { return _ty; }
00310 INT32 Id(void) const { return _id; }
00311 PT_ATTR Attr(void) const { return ai._attr; }
00312 BOOL Not_addr_saved(void) const { return ai._attr & PT_ATTR_NOT_ADDR_SAVED; }
00313 BOOL Not_addr_passed(void) const { return ai._attr & PT_ATTR_NOT_ADDR_PASSED; }
00314 BOOL Local(void) const { return ai._attr & PT_ATTR_LOCAL; }
00315 BOOL Global(void) const { return ai._attr & PT_ATTR_GLOBAL; }
00316 BOOL Named(void) const { return ai._attr & PT_ATTR_NAMED; }
00317 BOOL Unnamed(void) const { return !Named(); }
00318 BOOL Const(void) const { return ai._attr & PT_ATTR_CONST; }
00319 BOOL Restricted(void) const { return ai._attr & PT_ATTR_RESTRICTED; }
00320 BOOL Unique_pt(void) const { return ai._attr & PT_ATTR_UNIQUE_PT; }
00321 BOOL F_param(void) const { return ai._attr & PT_ATTR_F_PARAM; }
00322 BOOL Dedicated(void) const { return ai._attr & PT_ATTR_DEDICATED; }
00323 BOOL No_alias(void) const { return ai._attr & PT_ATTR_NO_ALIAS; }
00324 BOOL Weak(void) const { return ai._attr & PT_ATTR_WEAK; }
00325 BOOL Weak_base(void) const { return ai._attr & PT_ATTR_WEAK_BASE; }
00326 BOOL Is_pointer(void) const { return ai._attr & PT_ATTR_IS_POINTER; }
00327 BOOL Safe_to_speculate(void) const { return ai._attr & PT_ATTR_SAFE_TO_SPECULATE; }
00328 BOOL Not_auto(void) const { return ai._attr & PT_ATTR_NOT_AUTO; }
00329 BOOL Formal(void) const { return ai._attr & PT_ATTR_FORMAL; }
00330 BOOL Default_vsym(void) const { return ai._attr & PT_ATTR_DEFAULT_VSYM; }
00331 BOOL Known_f90_pointer(void) const
00332 { return ai._attr & PT_ATTR_F90_POINTER; }
00333 BOOL Known_not_f90_pointer(void) const
00334 { return ai._attr & PT_ATTR_NOT_F90_POINTER; }
00335 BOOL Not_f90_target(void) const { return ai._attr & PT_ATTR_NOT_F90_TARGET; }
00336 BOOL Not_alloca_mem(void) const { return ai._attr & PT_ATTR_NOT_ALLOCA_MEM; }
00337 BOOL Extended(void) const { return ai._attr & PT_ATTR_EXTENDED; }
00338
00339
00340
00341 void Set_expr_kind(EXPR_KIND expr_kind) { ai._expr_kind = expr_kind; }
00342 void Set_base_kind(BASE_KIND base_kind) { ai._base_kind = base_kind; }
00343 void Set_ofst_kind(OFST_KIND ofst_kind) { ai._ofst_kind = ofst_kind; }
00344 void Set_unused() { ai._unused = 0; }
00345 void Set_base(ST *base) { ai._base = base; }
00346 void Set_byte_ofst(mINT64 ofst) { ai._byte_ofst = ofst; }
00347 void Set_byte_size(mINT64 size) { ai._byte_size = size; }
00348 void Set_bit_ofst_size(mUINT8 ofst, mUINT8 size) {
00349 ai._bit_ofst = ofst;
00350 ai._bit_size = size;
00351 }
00352 void Set_based_sym(ST *sym) { ai._based_sym = sym; }
00353 void Set_based_sym_depth(UINT32 d) { ai._based_sym_depth = (d > 7) ? 7 : d; }
00354 void Set_alias_class(const IDTYPE alias_class)
00355 {
00356 if (alias_class <= WOPT_Alias_Class_Limit) {
00357 ai._alias_class = alias_class;
00358 }
00359 else {
00360 ai._alias_class = PESSIMISTIC_AC_ID;
00361 }
00362 }
00363 void Set_ip_alias_class(const IDTYPE iac)
00364 {
00365 if (iac <= WOPT_Ip_Alias_Class_Limit) {
00366 ai._ip_alias_class = iac;
00367 }
00368 else {
00369 ai._ip_alias_class = PESSIMISTIC_AC_ID;
00370 }
00371 }
00372 void Set_ty(TY_IDX ty) { _ty = ty; }
00373 void Set_id(INT32 id) { _id = id; }
00374 void Set_attr(PT_ATTR attr) { ai._attr = attr; }
00375 void Set_not_addr_saved(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_NOT_ADDR_SAVED); }
00376 void Set_not_addr_passed(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_NOT_ADDR_PASSED); }
00377 void Set_local(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_LOCAL); }
00378 void Set_global(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_GLOBAL); }
00379 void Set_named(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_NAMED); }
00380 void Set_const(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_CONST); }
00381 void Set_restricted(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_RESTRICTED); }
00382 void Set_unique_pt(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_UNIQUE_PT); }
00383 void Set_F_param(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_F_PARAM); }
00384 void Set_dedicated(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_DEDICATED); }
00385 void Set_no_alias(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_NO_ALIAS); }
00386 void Set_weak(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_WEAK); }
00387 void Set_weak_base(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_WEAK_BASE); }
00388 void Set_is_pointer(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_IS_POINTER); }
00389 void Set_safe_to_speculate(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_SAFE_TO_SPECULATE); }
00390 void Set_not_auto(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_NOT_AUTO); }
00391 void Set_formal(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_FORMAL); }
00392 void Set_default_vsym(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_DEFAULT_VSYM); }
00393 void Set_known_f90_pointer(void)
00394 {
00395 Is_True(!Known_not_f90_pointer(),
00396 ("POINTS_TO: f90_pointer attributes inconsistent"));
00397 ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_F90_POINTER);
00398 }
00399 void Set_known_not_f90_pointer(void)
00400 {
00401 Is_True(!Known_f90_pointer(),
00402 ("POINTS_TO: f90_pointer attributes inconsistent"));
00403 ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_NOT_F90_POINTER);
00404 }
00405 void Set_not_f90_target(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_NOT_F90_TARGET); }
00406 void Set_not_alloca_mem(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_NOT_ALLOCA_MEM); }
00407 void Set_extended(void) { ai._attr = (PT_ATTR) (ai._attr | PT_ATTR_EXTENDED); }
00408
00409 void Reset_attr(void) { ai._attr = PT_ATTR_NONE; }
00410 void Reset_not_addr_saved(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_NOT_ADDR_SAVED); }
00411 void Reset_not_addr_passed(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_NOT_ADDR_PASSED); }
00412 void Reset_local(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_LOCAL); }
00413 void Reset_global(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_GLOBAL); }
00414 void Reset_named(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_NAMED); }
00415 void Reset_const(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_CONST); }
00416 void Reset_restricted(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_RESTRICTED); }
00417 void Reset_unique_pt(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_UNIQUE_PT); }
00418 void Reset_F_param(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_F_PARAM); }
00419 void Reset_dedicated(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_DEDICATED); }
00420 void Reset_no_alias(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_NO_ALIAS); }
00421 void Reset_weak(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_WEAK); }
00422 void Reset_weak_base(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_WEAK_BASE); }
00423 void Reset_is_pointer(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_IS_POINTER); }
00424 void Reset_safe_to_speculate(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_SAFE_TO_SPECULATE); }
00425 void Reset_not_auto(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_NOT_AUTO); }
00426 void Reset_formal(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_FORMAL); }
00427 void Reset_default_vsym(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_DEFAULT_VSYM); }
00428 void Reset_known_f90_pointer(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_F90_POINTER); }
00429 void Reset_known_not_f90_pointer(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_NOT_F90_POINTER); }
00430 void Reset_not_f90_target(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_NOT_F90_TARGET); }
00431 void Reset_not_alloca_mem(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_NOT_ALLOCA_MEM); }
00432 void Reset_extended(void) { ai._attr = (PT_ATTR) (ai._attr & ~PT_ATTR_EXTENDED); }
00433
00434 void Init(void) {
00435
00436 Set_expr_kind(EXPR_IS_INVALID);
00437 Set_base_kind(BASE_IS_INVALID);
00438 Set_ofst_kind(OFST_IS_INVALID);
00439 Set_unused();
00440 Set_based_sym_depth(0);
00441 Set_base((ST*)NULL);
00442 Set_byte_ofst(0);
00443 Set_byte_size(0);
00444 Set_bit_ofst_size(0,0);
00445 Set_based_sym((ST*)NULL);
00446 Set_ty(0);
00447 Set_id(0);
00448 Set_alias_class(OPTIMISTIC_AC_ID);
00449 Set_ip_alias_class(OPTIMISTIC_AC_ID);
00450
00451
00452 Set_attr(PT_ATTR_NONE);
00453 }
00454
00455
00456 BOOL Same_base(const POINTS_TO *) const;
00457
00458
00459 BOOL Different_base(const POINTS_TO *) const;
00460
00461
00462 BOOL Overlap(const POINTS_TO *) const;
00463
00464
00465
00466 BOOL Similar(const POINTS_TO *pt) const {
00467 if (Expr_kind() == pt->Expr_kind() &&
00468 Base_kind() == pt->Base_kind() &&
00469 Ofst_kind() == pt->Ofst_kind() &&
00470 Base_kind() == BASE_IS_FIXED &&
00471 Ofst_kind() == OFST_IS_FIXED &&
00472 Base() == pt->Base() &&
00473 Byte_Ofst() == pt->Byte_Ofst() &&
00474 Byte_Size() == pt->Byte_Size())
00475 return TRUE;
00476
00477 if ((F_param() && pt->F_param()) &&
00478 (Based_sym() == pt->Based_sym()))
00479 return TRUE;
00480
00481 return FALSE;
00482 }
00483
00484 IDTYPE Alias_class(void) const { return ai._alias_class; }
00485
00486 IDTYPE Ip_alias_class(void) const { return ai._ip_alias_class; }
00487
00488 void Shift_ofst(mINT64 shift)
00489 { Set_byte_ofst( Byte_Ofst() + shift ); }
00490
00491
00492 BOOL Base_is_fixed(void) const
00493 { return Base_kind() == BASE_IS_FIXED; }
00494
00495 BOOL Int_is_constant(void) const
00496 { return (Ofst_kind() == OFST_IS_FIXED); }
00497
00498 mINT64 Int_const_val(void) const
00499 { return Byte_Ofst(); }
00500
00501 void Set_const_val(mINT64 val)
00502 { Set_byte_ofst(val); Set_ofst_kind(OFST_IS_FIXED); }
00503
00504
00505 void Meet_info_from_alias_class(const POINTS_TO *);
00506
00507
00508 void Meet(const POINTS_TO *, ST *);
00509
00510
00511 void Copy_fully(const POINTS_TO *p)
00512 { *this = *p; }
00513
00514 void Copy_fully(const POINTS_TO &p)
00515 { *this = p; }
00516
00517
00518
00519 void Copy_non_sticky_info(const POINTS_TO *p)
00520 {
00521 BOOL is_unique_pt = Unique_pt();
00522 BOOL is_restricted = Restricted();
00523 ST *based_sym = Based_sym();
00524 *this = *p;
00525 if (is_unique_pt) {
00526 Set_unique_pt();
00527 Set_based_sym(based_sym);
00528 }
00529 if (is_restricted) {
00530 Set_restricted();
00531 Set_based_sym(based_sym);
00532 }
00533 }
00534
00535
00536
00537 void Copy_non_sticky_info(const POINTS_TO &p)
00538 {
00539 BOOL is_unique_pt = Unique_pt();
00540 BOOL is_restricted = Restricted();
00541 ST *based_sym = Based_sym();
00542 *this = p;
00543 if (is_unique_pt) {
00544 Set_unique_pt();
00545 Set_based_sym(based_sym);
00546 }
00547 if (is_restricted) {
00548 Set_restricted();
00549 Set_based_sym(based_sym);
00550 }
00551 }
00552
00553
00554 void Analyze_ST(ST *st, INT64 byte_ofst, INT64 byte_size, UINT8 bit_ofst,
00555 UINT8 bit_size, TY_IDX ty, BOOL has_equiv);
00556
00557 void Analyze_ST_as_base(ST *, INT64, TY_IDX);
00558
00559 void Analyze_WN_expr(WN *);
00560
00561 #ifdef __cplusplus
00562 template <class SYMTAB> void Analyze_Ldid_Base(WN *wn, const SYMTAB &symtab);
00563 template <class SYMTAB> void Analyze_Parameter_Base(WN *wn, const SYMTAB &symtab);
00564 template <class SYMTAB> void Analyze_WN_expr(WN *wn, const SYMTAB &symtab);
00565 #endif
00566
00567 void Analyze_Lda_Base(WN *, const OPT_STAB &);
00568 void Analyze_Lda_Base(WN *, const STAB_ADAPTER &);
00569 void Lower_to_base(WN *);
00570
00571 POINTS_TO() {}
00572 POINTS_TO(ST *st, BOOL indirect = FALSE) {
00573 Init();
00574 if (indirect)
00575 Analyze_ST_as_base(st, 0, 0);
00576 else
00577 Analyze_ST(st, 0, ST_size(st), 0, 0, 0, TRUE);
00578 if (Byte_Size() == 0)
00579 Set_ofst_kind(OFST_IS_UNKNOWN);
00580 }
00581 POINTS_TO(ST *st, INT64 ofst, INT64 size, BOOL indirect = FALSE) {
00582 Init();
00583 if (indirect)
00584 Analyze_ST_as_base(st, ofst, 0);
00585 else
00586 Analyze_ST(st, ofst, size, 0, 0, 0, TRUE);
00587 if (Byte_Size() == 0)
00588 Set_ofst_kind(OFST_IS_UNKNOWN);
00589 }
00590 POINTS_TO(ST* st, INT64 byte_ofst, INT64 byte_size, UINT8 bit_ofst,
00591 UINT8 bit_size, BOOL indirect = FALSE) {
00592 Init();
00593 if (indirect)
00594 Analyze_ST_as_base(st, byte_ofst, 0);
00595 else
00596 Analyze_ST(st, byte_ofst, byte_size, bit_ofst, bit_size, 0, TRUE);
00597 if (Byte_Size() == 0)
00598 Set_ofst_kind(OFST_IS_UNKNOWN);
00599 }
00600
00601
00602 void Print(FILE *fp=stderr) const;
00603 };
00604
00605
00606
00607
00608 class POINTS_TO_NODE : public SLIST_NODE {
00609 DECLARE_SLIST_NODE_CLASS(POINTS_TO_NODE)
00610 private:
00611 POINTS_TO *_pt;
00612 POINTS_TO_NODE(void);
00613 POINTS_TO_NODE(const POINTS_TO_NODE&);
00614 POINTS_TO_NODE& operator = (const POINTS_TO_NODE&);
00615 public:
00616 POINTS_TO_NODE(POINTS_TO *pt) { _pt = pt; }
00617 ~POINTS_TO_NODE(void) {}
00618 POINTS_TO *Pt(void) const { return _pt; }
00619 };
00620
00621
00622
00623
00624 class POINTS_TO_LIST : public SLIST {
00625 DECLARE_SLIST_CLASS (POINTS_TO_LIST, POINTS_TO_NODE)
00626 private:
00627 POINTS_TO_LIST(const POINTS_TO_LIST&);
00628 POINTS_TO_LIST& operator = (const POINTS_TO_LIST&);
00629 public:
00630 void Prepend( POINTS_TO *pt, MEM_POOL *pool );
00631 };
00632
00633
00634 class POINTS_TO_ITER : public SLIST_ITER {
00635 private:
00636 DECLARE_SLIST_ITER_CLASS (POINTS_TO_ITER, POINTS_TO_NODE, POINTS_TO_LIST)
00637 POINTS_TO_ITER(const POINTS_TO_ITER&);
00638 POINTS_TO_ITER& operator = (const POINTS_TO_ITER&);
00639 public:
00640 ~POINTS_TO_ITER(void) {}
00641 POINTS_TO_NODE *First_elem(void) { return First(); }
00642 POINTS_TO_NODE *Next_elem(void) { return Next(); }
00643 };
00644
00645
00646 #ifdef Is_True_On
00647 extern void CHECK_POINTS_TO(POINTS_TO *);
00648 #else
00649 #define CHECK_POINTS_TO(pt)
00650 #endif
00651
00652
00653 void Expand_ST_into_base_and_ofst(ST *st, INT64 st_ofst, ST ** base, INT64 *ofst);
00654
00655 template <class SYMTAB> WN *Find_addr_recur(WN *, const SYMTAB &);
00656
00657 inline static BOOL Is_FORTRAN()
00658 {
00659 const PU& pu = Get_Current_PU ();
00660 return (PU_f77_lang (pu) || PU_f90_lang (pu));
00661 }
00662
00663 template <class SYMTAB>
00664 ST *Is_nested_call(const WN *wn, const SYMTAB &symtab);
00665
00666 extern ST *Is_nested_call(const WN *wn);
00667
00668
00669
00670
00671
00672 template <class SYMTAB>
00673 void POINTS_TO::Analyze_Ldid_Base(WN *wn_ldid, const SYMTAB &stab)
00674 {
00675 ST *st = stab.St_ptr(wn_ldid);
00676 INT64 ofst = WN_offset(wn_ldid);
00677 TY_IDX ty = WN_ty(wn_ldid);
00678 Analyze_ST_as_base(st, ofst, ty);
00679 Set_ofst_kind(OFST_IS_UNKNOWN);
00680 }
00681
00682
00683 template <class SYMTAB>
00684 WN *Find_addr_recur(WN *wn, const SYMTAB &stab)
00685 {
00686 if (wn == NULL) return NULL;
00687 switch (WN_operator(wn)) {
00688 case OPR_PARM:
00689
00690 if (WN_Parm_By_Reference(wn) && WN_kid_count(wn))
00691 return Find_addr_recur(WN_kid0(wn), stab);
00692
00693 return NULL;
00694 case OPR_LDA:
00695 return wn;
00696 case OPR_LDID:
00697 {
00698 ST *st = stab.St_ptr(wn);
00699 if (Is_FORTRAN() && ST_sclass(st) == SCLASS_FORMAL &&
00700 ! ST_is_value_parm(st))
00701 return wn;
00702 if (ST_pt_to_unique_mem(st)) {
00703 TY_IDX ty = WN_ty(wn);
00704 if (TY_kind(Ty_Table[ty]) != KIND_POINTER) {
00705 TY_IDX new_ty = Make_Pointer_Type(ty);
00706 WN_set_ty(wn, new_ty);
00707
00708 DevWarn("Fixing TY %s of LDID <%s> to a pointer type because the ST has PT_TO_UNIQUE_MEM set",
00709 TY_name(ty) ? TY_name(ty) : "noname",
00710 ST_name(st) ? ST_name(st) : "noname");
00711 }
00712 return wn;
00713 }
00714 TY_IDX ty = WN_ty(wn);
00715 if (TY_kind(Ty_Table[ty]) == KIND_POINTER)
00716 return wn;
00717 Is_True(!TY_is_restrict(ty),
00718 ("__restrict object must be KIND_POINTER"));
00719 return NULL;
00720 }
00721 case OPR_ARRAY:
00722 return Find_addr_recur(WN_kid0(wn), stab);
00723 case OPR_ADD:
00724 {
00725 WN *ret_wn;
00726 for (INT32 i = 0; i < WN_kid_count(wn); i++)
00727 if ((ret_wn = Find_addr_recur(WN_kid(wn,i), stab)) != NULL)
00728 return ret_wn;
00729 return NULL;
00730 }
00731 case OPR_SUB:
00732 return Find_addr_recur(WN_kid(wn,0), stab);
00733 default:
00734 return NULL;
00735 }
00736 }
00737
00738
00739 template <class SYMTAB>
00740 void POINTS_TO::Analyze_Parameter_Base(WN *wn, const SYMTAB &stab)
00741 {
00742 Set_expr_kind(EXPR_IS_ADDR);
00743 Set_base_kind(BASE_IS_UNKNOWN);
00744 Set_ofst_kind(OFST_IS_UNKNOWN);
00745 WN *wn_lda;
00746 switch (WN_operator(wn)) {
00747 case OPR_LDA:
00748 Analyze_Lda_Base(wn, stab);
00749 Lower_to_base(NULL);
00750 break;
00751 case OPR_LDID:
00752 Analyze_Ldid_Base(wn, stab);
00753 Set_ofst_kind(OFST_IS_UNKNOWN);
00754 break;
00755
00756 case OPR_ARRAY:
00757 default:
00758 wn_lda = Find_addr_recur(wn, stab);
00759 if (wn_lda != NULL) {
00760 if (WN_operator(wn_lda) == OPR_LDA) {
00761 Analyze_Lda_Base(wn_lda, stab);
00762 Lower_to_base(NULL);
00763 } else if (WN_operator(wn_lda) == OPR_LDID) {
00764 Analyze_Ldid_Base(wn_lda, stab);
00765 Lower_to_base(NULL);
00766
00767 }
00768 }
00769 break;
00770 }
00771 }
00772
00773
00774 template <class SYMTAB>
00775 void POINTS_TO::Analyze_WN_expr(WN *wn, const SYMTAB &stab)
00776 {
00777 OPERATOR opr = WN_operator(wn);
00778 switch ( opr ) {
00779 case OPR_LDID:
00780 case OPR_STID:
00781 case OPR_LDBITS:
00782 case OPR_STBITS:
00783 {
00784 ST *st = stab.St_ptr(wn);
00785 if (ST_sclass(st) != SCLASS_UNKNOWN) {
00786 TY_IDX ty = ST_type(st);
00787 INT64 ofst = WN_offset(wn);
00788 INT64 size = MTYPE_size_min(WN_desc(wn)) >> 3;
00789 if (opr == OPR_LDBITS || opr == OPR_STBITS)
00790 Analyze_ST (st, ofst, size, WN_bit_offset (wn), WN_bit_size
00791 (wn), ty, TRUE );
00792 else
00793 Analyze_ST(st, ofst, size, 0, 0, ty, TRUE );
00794 return;
00795 }
00796 }
00797 break;
00798 case OPR_ILDBITS:
00799 case OPR_ISTBITS:
00800 case OPR_ILOAD:
00801 case OPR_MLOAD:
00802 case OPR_PARM:
00803 case OPR_ISTORE:
00804 case OPR_MSTORE:
00805 {
00806 WN *wn_lda = Find_addr_recur(
00807 OPERATOR_is_store(opr) ? WN_kid1(wn) : WN_kid0(wn), stab);
00808 if (wn_lda != NULL) {
00809 if (WN_operator(wn_lda) == OPR_LDA) {
00810 ST *st = stab.St_ptr(wn_lda);
00811 if (ST_sclass(st) != SCLASS_UNKNOWN) {
00812 Analyze_Lda_Base(wn_lda, stab);
00813 Lower_to_base(NULL);
00814 return;
00815 }
00816 } else if (WN_operator(wn_lda) == OPR_LDID) {
00817 Analyze_Ldid_Base(wn_lda, stab);
00818 Lower_to_base(NULL);
00819 return;
00820 }
00821 }
00822 }
00823 break;
00824 default:
00825 break;
00826 }
00827 Init();
00828 }
00829
00830
00831
00832
00833 template <class SYMTAB>
00834 ST *Is_nested_call(const WN *wn, const SYMTAB &symtab)
00835 {
00836 ST *call_st = NULL;
00837 INT32 num_parms = WN_kid_count(wn);
00838 OPERATOR opr = WN_operator(wn);
00839 if (opr == OPR_CALL) {
00840 call_st = WN_st(wn);
00841 } else if (opr == OPR_ICALL)
00842 num_parms--;
00843
00844
00845
00846
00847
00848
00849 ST *nested_func = NULL;
00850
00851 for ( INT parmkid = 0; parmkid < num_parms; parmkid++ ) {
00852 WN *parm = WN_kid(wn, parmkid);
00853 if ( WN_operator(parm) == OPR_PARM ) {
00854 WN *actual_parm = WN_kid0(parm);
00855 if ( WN_operator(actual_parm) == OPR_LDA ) {
00856
00857
00858
00859
00860
00861 ST *lda_st = symtab.St_ptr(actual_parm);
00862 if ( ST_class(lda_st) == CLASS_FUNC &&
00863 PU_is_nested_func (Pu_Table[ST_pu (lda_st)])
00864 )
00865 nested_func = lda_st;
00866 }
00867 }
00868 }
00869
00870 if ( nested_func == NULL && call_st != NULL &&
00871 PU_is_nested_func (Pu_Table[ST_pu (call_st)])
00872 )
00873 nested_func = call_st;
00874
00875 return nested_func;
00876 }
00877
00878 #endif // opt_points_to_INCLUDED