Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
opt_points_to.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines