Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2 of the GNU General Public License as 00007 published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU General Public License along 00021 with this program; if not, write the Free Software Foundation, Inc., 59 00022 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00023 00024 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00025 Mountain View, CA 94043, or: 00026 00027 http://www.sgi.com 00028 00029 For further information regarding this notice, see: 00030 00031 http://oss.sgi.com/projects/GenInfo/NoticeExplan 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" // for CXX_NEW 00043 #include "opcode.h" 00044 #include "wn.h" 00045 #include "config_wopt.h" // for WOPT_Alias_Class_Limit, 00046 // WOPT_Ip_Alias_Class_Limit 00047 00048 00049 typedef struct bs BS; 00050 00051 // interface to Mongoose symbol table 00052 struct STAB_ADAPTER { 00053 ST *St_ptr (WN *wn) const { return WN_st (wn); } 00054 }; 00055 00056 class OPT_STAB; 00057 00058 // ALIAS ANALYSIS and POINTS TO ANALYSIS 00059 // 00060 // The Mongoose optimizer distinguishes points-to analysis from alias 00061 // analysis. The former analyzes the lvalue of an expression and 00062 // summarizes the information into a POINTS_TO instance. 00063 // 00064 // The latter uses the POINTS_TO information to perform alias analysis. 00065 // 00066 // The POINTS_TO information is gathered in two methods: 00067 // 1) Flow free 00068 // such as determining the symbol, the type, the qualifiers, ... 00069 // 2) Flow sensitive 00070 // such as determining the value of a pointer, ... 00071 // 00072 // The alias analysis is performed in 3 domains: 00073 // 1) symbol to symbol 00074 // This happens in FORTRAN common blocks, C unions ... 00075 // 2) memop to symbol 00076 // This is used by SSA 00077 // 3) memop to memop 00078 // This is not used by SSA, but required by the OPT/CG ... 00079 // 4) call to symbol 00080 // This is used by SSA. 00081 // 5) call to memop 00082 // This is used by SSA. 00083 // 00084 00085 00086 // EXPR_KIND keeps track of the kind of the pointer expression 00087 // It is used only during FSA. 00088 // 00089 // INVALID -- the compiler should assert when this value is used. 00090 // BEING_PROCESSED -- this pointer expression is being processed. 00091 // assume the most optimistic value in FSA. 00092 // INT -- the expression contains an integer expression. 00093 // ADDR -- the expression is based on some variable. 00094 // UNKNOWN -- the most conservative assumption should be made. 00095 // ANY -- the most optimistic assumption should be made. 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, // expr is unknown, take it conservatively 00103 EXPR_IS_ANY // expr is unknown, but can be combined with anything 00104 }; 00105 00106 // BASE_KIND qualifies what type of information *base contains. 00107 // 00108 // INVALID -- should cause assertion. 00109 // FIXED -- the memop is based on a global or local variable. 00110 // DYNAMIC -- the base is determined at runtime. 00111 // UNKNOWN -- no information 00112 // 00113 // The base field in the POINTS_TO data structure can be 00114 // 1) a static address (represented by a ST *) 00115 // 2) a dynamic computed value 00116 // 2a) a WHIRL expression (represented by a WN *) 00117 // 2b) a CHI node (represented by a CHI_NODE *) 00118 // 2c) a PHI node (represented by a PHI_NODE *) 00119 // 2d) it is not defined in this PU (i.e, parameter or global 00120 // or even undefined locals). 00121 // (Represented by the aux_id.) 00122 // 00123 enum BASE_KIND { 00124 BASE_IS_INVALID, 00125 BASE_IS_FIXED, // base() is ST* 00126 BASE_IS_DYNAMIC, // base() is some definition 00127 BASE_IS_UNKNOWN, // base() is NULL 00128 // *** Do not add new base_kind after this line *** 00129 MAX_BASE_KIND // For creating array indexed by BASE_KIND 00130 }; 00131 00132 00133 // OFTS_KIND qualifies what type of information the ofst and size field contains 00134 // 00135 // INVALID -- should assert 00136 // FIXED -- the ofst field denotes the lower range of access 00137 // and the ofst+size denotes the upper range of access 00138 // UNKNOWN -- the ofst field contains no useful information 00139 // 00140 enum OFST_KIND { 00141 OFST_IS_INVALID, // invalid ofst kind 00142 OFST_IS_FIXED, // offset is fixed (available in the ofst field) 00143 OFST_IS_UNKNOWN // offset is unknown 00144 }; 00145 00146 00147 // Contains single-bit attributes. 00148 // 00149 // Notice the 0 is the default (conservative) values for every attribute. 00150 // Example: the default attribute for a variable is address taken. 00151 // 00152 // If a variable is not address taken and we assume it is, 00153 // alias analysis is not accurate but still produces a correct answer. 00154 // However, it the variable is address taken and we assume it is not, 00155 // then alias analysis will produce an incorrect answer. 00156 // 00157 // NOT_ADDR_SAVED -- The address of this variable is not saved into a variable. 00158 // NOT_ADDR_PASSED -- The address of this variable is not passed to some routine. 00159 // LOCAL -- The variable determined to be local variable. 00160 // This bit does not necessarily set for all locals. 00161 // NAMED -- This memory operation accesses a named variable. 00162 // CONST -- This memory operation accesses read-only 00163 // data (i.e., data that we can assume is not 00164 // written by anything in the program [except 00165 // possibly runtime initializer/constructor?]). 00166 // RESTRICTED -- This memory operation is based on a restricted pointer. 00167 // UNIQUE_PT -- This memory operation is based on a unique pointer. 00168 // F_PARAM -- This memory operation is based on a Fortran parameter. 00169 // NO_ALIAS -- This memory operation is accessed a variable 00170 // that has no alias except itself. 00171 // WEAK -- This memory operation writes to a weak symbol. 00172 // WEAK_BASE -- This symbol is the base(target) of a weak symbol. 00173 // IS_POINTER -- Represents a range of address of a pointer. 00174 // SAFE_TO_SPECULATE -- safe to speculate. 00175 // NOT_AUTO -- It is known that if this variable has an 00176 // initializer, it is initialized at compile/link 00177 // time (not run time). C/C++ "automatic" 00178 // locals do not have this bit set. C/C++ 00179 // globals and "static" do. Currently, this is 00180 // used only when the CONST attribute is also 00181 // set; it indicates that we can safely say 00182 // this item does not alias. With CONST and 00183 // without NOT_AUTO, we must at least say the 00184 // item's initialization aliases with its uses, 00185 // so the uses don't get scheduled first. 00186 // FORMAL -- it is a formal parameter passed to this routine. 00187 // Needs this bit because after data layout, formal parameters 00188 // and local variables are layout w.r.t. to $SP. 00189 // 00190 enum PT_ATTR { 00191 PT_ATTR_NONE = 0, 00192 PT_ATTR_NOT_ADDR_SAVED = 0x1, // address is not saved 00193 PT_ATTR_NOT_ADDR_PASSED = 0x2, // address is not passed 00194 PT_ATTR_LOCAL = 0x4, // local variable 00195 PT_ATTR_GLOBAL = 0x8, // global variable 00196 PT_ATTR_NAMED = 0x10, // reference a named variable 00197 PT_ATTR_CONST = 0x20, // the variable is read-only 00198 PT_ATTR_RESTRICTED = 0x40, // pointer gives restricted access 00199 PT_ATTR_UNIQUE_PT = 0x80, // pointer gives exclusive access 00200 PT_ATTR_F_PARAM = 0x100, // fortran call-by-ref parameter 00201 PT_ATTR_DEDICATED = 0x200, // dedicated register or memory 00202 // location 00203 PT_ATTR_NO_ALIAS = 0x400, // this object has no alias 00204 00205 // Weak is different from the other attr. 00206 // When two POINTS_TO are combined, it either one is weak, then 00207 // the combined one is weak 00208 PT_ATTR_WEAK = 0x800, // weak symbol 00209 PT_ATTR_WEAK_BASE = 0x1000, // base of a weak symbol 00210 PT_ATTR_IS_POINTER = 0x2000, // is a pointer content (not memory ref) 00211 PT_ATTR_SAFE_TO_SPECULATE = 0x4000, // safe to speculate 00212 PT_ATTR_NOT_AUTO = 0x8000, // static init is not at run time 00213 PT_ATTR_FORMAL = 0x10000, // is a formal parameter 00214 PT_ATTR_DEFAULT_VSYM = 0x20000, // is the default vsym, alias to 00215 // everything 00216 PT_ATTR_F90_POINTER = 0x40000, // access is known to be through 00217 // an f90 pointer 00218 PT_ATTR_NOT_F90_POINTER = 0x80000, // access is known not to be 00219 // through an f90 pointer 00220 PT_ATTR_NOT_F90_TARGET = 0x100000, // access is to memory that may 00221 // be pointed to by f90 pointer 00222 PT_ATTR_NOT_ALLOCA_MEM = 0x200000, // this access can safely be 00223 // moved past stack pointer updates 00224 PT_ATTR_EXTENDED = 0x400000 // used by alias manager to represent 00225 // a consecutive array of POINTS_TO 00226 // 23 of 32 bits used 00227 }; 00228 00229 00230 // ALIAS_INFO is the subset of POINTS_TO that will be passed in .B file. 00231 // 00232 class ALIAS_INFO { 00233 00234 friend class POINTS_TO; 00235 mUINT32 _expr_kind :3; // one of EXPR_KIND 00236 mUINT32 _base_kind :3; // one of BASE_KIND 00237 mUINT32 _ofst_kind :2; // one of OFST_KIND 00238 mUINT32 _based_sym_depth:3;// used for disjoint 00239 mUINT32 _unused : 5; // unused bits for future expansion 00240 mUINT32 _bit_ofst : 8; // bit offset (for bit fields) 00241 mUINT32 _bit_size : 8; // bit size (for bit fields) 00242 // _bit_size should be zero when this is 00243 // not a bit field. When it is 00244 // non-zero, _byte_ofst/_byte_size 00245 // gives the ofst/size of the container 00246 // of the bit field, and _bit_ofst/_bit_size 00247 // gives the bit ofst/size within the 00248 // container 00249 PT_ATTR _attr; // PT_ATTR attributes 00250 INT64 _byte_ofst; // offset from base -- controlled by _ofst_kind 00251 UINT64 _byte_size; // size of access -- controlled by _ofst_kind 00252 ST *_base; // base symbol -- controlled by _base_kind 00253 ST *_based_sym; // for restricted pointer, Fortran ref-param ... 00254 IDTYPE _alias_class; // which equivalence class this 00255 // memop is in, according to per-PU 00256 // analysis 00257 IDTYPE _ip_alias_class; // which equivalence class this 00258 // memop is in, according to 00259 // whole-program analysis 00260 }; 00261 00262 00263 // for alias classification 00264 const IDTYPE OPTIMISTIC_AC_ID = 0; 00265 const IDTYPE PESSIMISTIC_AC_ID = 1; 00266 00267 00268 // POINTS_TO is a structure to contain Points-to analysis results. 00269 // 00270 // Points-to analysis determines for the memop 00271 // 1. base pointer 00272 // 2. types of memory access (e.g. to local variable, global variable, ...) 00273 // 3. access range (ofst, size) 00274 // 00275 // !!! the fields make sense only if EXPR_IS_ADDR !!! 00276 // 00277 class POINTS_TO { 00278 private: 00279 ALIAS_INFO ai; 00280 TY_IDX _ty; // user-declared type for this memop 00281 INT32 _id; // only used by the emitter. 00282 00283 // Force everyone to use Copy_non_sticky_info or Copy_fully by 00284 // declaring an private assignment operator and an undefined copy 00285 // constructor. 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 // Member access functions 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 // Set members 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 // Set fields in POINTS_TO to invalid for error detection. 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 // The default attributes: 00452 Set_attr(PT_ATTR_NONE); 00453 } 00454 00455 // Return TRUE if bases are the same. Return FALSE if don't know. 00456 BOOL Same_base(const POINTS_TO *) const; 00457 00458 // Return TRUE if bases are different. Return FALSE if don't know. 00459 BOOL Different_base(const POINTS_TO *) const; 00460 00461 // Check whether offset overlaps. Their bases must be the same. 00462 BOOL Overlap(const POINTS_TO *) const; 00463 00464 // Check if PTs are similar, used in creating region bounds and rejecting 00465 // duplicates 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) // shift offset by that amount 00489 { Set_byte_ofst( Byte_Ofst() + shift ); } 00490 00491 // Return TRUE if base is fixed. 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); } // overloaded ofst_kind 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 // Merge the information from alias classification for two POINTS_TO's 00505 void Meet_info_from_alias_class(const POINTS_TO *); 00506 00507 // Merge two points to information 00508 void Meet(const POINTS_TO *, ST *); 00509 00510 // Copy a POINTS_TO structure 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 // Copy a POINTS_TO structure except for its sticky parts (i.e., the 00518 // parts related to unique_pt and restrict. 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 // Copy a POINTS_TO structure except for its sticky parts (i.e., the 00536 // parts related to unique_pt and restrict. 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 // Compute the POINTS_TO info for an ST 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 // Print (for debugging) 00602 void Print(FILE *fp=stderr) const; 00603 }; 00604 00605 00606 // POINTS_TO_NODE: contains the points_to item 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 // POINTS_TO_LIST is a internal linked list 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 // Lower ST into the <base,ofst> form 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 // Implementation stuff originally from opt_points_to.cxx, since g++ (rightly) 00669 // doesn't do implicit inclusion of .cxx files. 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 // Look for a LDA/LDID node recursively 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 // if it is called by reference, LDID is a addr expr 00690 if (WN_Parm_By_Reference(wn) && WN_kid_count(wn)) 00691 return Find_addr_recur(WN_kid0(wn), stab); 00692 // otherwise, there is no address expression 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 // Detect problem shown up in PV 652586. 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: // no information 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 // ignore the range. Passing A[i] does not mean only passing one element. 00767 } 00768 } 00769 break; 00770 } // switch 00771 } 00772 00773 // Templatize symbol table 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 /* has equiv */); 00792 else 00793 Analyze_ST(st, ofst, size, 0, 0, ty, TRUE /* assume has equiv */); 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 } // switch 00827 Init(); 00828 } 00829 00830 // returns NULL if not a nested call 00831 // global function, can be called with symtab or aux_stab 00832 // used by OPT_STAB::Add_nested_call_mu_chi and REGION_BOUNDS:grb 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 // nested procedure? 00845 // SPECIAL CASE: Check if any of the parameters is an LDA of 00846 // a nested function. If so, we consider this to also be a call 00847 // to that function. Only do this for fortran because that's the 00848 // only language so far that supports nested functions. 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 // tricky: 00857 // for stab == OPT_STAB it is 00858 // OPT_STAB::St_idx --> aux_stab[WN_aux(wn)].St() 00859 // for stab == STAB_ADAPTER, it is 00860 // STAB_ADAPTER::St_idx --> WN_st(wn) 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