Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
opt_alias_rule.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 //-*-c++-*-
00037 /* ====================================================================
00038 * ====================================================================
00039 *
00040 *
00041 * Revision history:
00042 *  04-APR-95 lo - Split from opt_alias.h
00043 *
00044 * Description:
00045 *
00046 * ====================================================================
00047 * ====================================================================
00048 */
00049 
00050 #ifndef opt_alias_rule_INCLUDED
00051 #define opt_alias_rule_INCLUDED "opt_alias_rule.h"
00052 #ifdef _KEEP_RCS_ID
00053 #endif /* _KEEP_RCS_ID */
00054 
00055 
00056 /* ========================================================================
00057 *
00058 *   ALIAS RULE 
00059 *   ----------
00060 *   This package implements the rules used in alias analysis.
00061 *   The set of rules used is run-time configurable by changing
00062 *   the ALIAS CONTEXT.  The rules are managed by the ALIAS MANAGER,
00063 *   which is the interface to LNO/CG/IPA.
00064 *   
00065 *   Overview
00066 *   --------
00067 *   The alias analysis is implemented as a rule-based system.
00068 *   Each alias rule is implemented by a function that returns
00069 *   TRUE or FALSE.  However, in one case, a function returns
00070 *   NO_READ_NO_WRITE, READ, WRITE, and READ_AND_WRITE in order
00071 *   to return better information.
00072 *
00073 *   The function returns FALSE if it determines that two memory 
00074 *   operations are not aliased.  It returns TRUE if 1) the rule
00075 *   determines that the memory operations are aliased; 2) the
00076 *   rule cannot draw any conclusions.
00077 *
00078 *   The rules examine a data structure called POINTS_TO that
00079 *   sumarize the alias information about memory operations.
00080 *   Each memory operation have its own POINTS_TO information.
00081 *
00082 *   Given a set of rules, two memory operation are not aliased if
00083 *   ANY of the rules returns FALSE.
00084 *
00085 *   The set of rules used for alias analysis is determined by
00086 *   the ALIAS CONTEXT.  The context is encoded in a 64-bit integer.
00087 *   Each rule is assigned a bit in the integer.  If the rule can
00088 *   be used for alias analysis, the bit corresponding to its
00089 *   position is set to 1.  The default ALIAS CONTEXT is
00090 *   initialized in the ALIAS MANAGER constructor by examining
00091 *   various command line options. e.g., -OPT:alias=typed ...
00092 *
00093 *   The ALIAS CONTEXT can also be manipulated in the midst of
00094 *   compilation by the use Get_context()/Set_context() interface.
00095 *   This interface is particularly useful to carry out alias
00096 *   analysis for inlined procedures.   For example,
00097 *   procedure A inlines procedure B.  Procedure A is written C
00098 *   and procedure B is written in Fortran.  After inlining,
00099 *   we still want to apply Fortran alias rules to the regions belonging
00100 *   to B.   During inlining, IPA would call Get_context() to 
00101 *   obtain the alias context of B and use a pragma to annotate
00102 *   the alias context to the expanded section of B inside A.
00103 *   During alias analysis, the default alias context (of B) is
00104 *   used.  When the module starts processing of the inlined IR,
00105 *   the module should read the pragma and use Set_context() to
00106 *   reconfigure the alias rule set.  Therefore, the Fortran alias
00107 *   rules can be applied to the inlined region.
00108 *   
00109 *   Similarly, if the procedure A is compiled with -OPT:alias=restrict,
00110 *   and procedure B is compiled with -OPT:alias=typed.  Even after inlining
00111 *   B to A, B will still be optimized with the -OPT:alias=typed.
00112 *
00113 *   WARNING:  The alias context is bound to the control flow structure!
00114 *   If a memory operation is moved out of region by code motion, then
00115 *   the alias context of the complement is used.  The implication is
00116 *   1) if a memory operation is moved from a region of aggressive alias rules
00117 *      to a lesser one, performance may suffer.
00118 *   2) if a memory operation is moved from a region of less aggressive rules
00119 *      to a more aggressive one,  incorrect results may happen.
00120 *   Therefore, we strongly discourage inlining routines of different
00121 *   alias levels together.
00122 *
00123 *   
00124 *   Exported functions
00125 *   ------------------
00126 *
00127 *   USE the interface defined here.  DO NOT CALL the alias rules 
00128 *   directly because the implementation should change without notification.
00129 *
00130 *   ALIAS_CONTEXT Get_context(void)
00131 *     returns the current alias context.
00132 *
00133 *   void Set_context(ALIAS_CONTEXT new_rule_set)
00134 *     Set the current alias context to new_rule_set.
00135 *
00136 *   BOOL Rule_enabled(ALIAS_CONTEXT rule)
00137 *     returns TRUE if the rule specified is allowed in the current 
00138 *     context.
00139 *
00140 *
00141 *   These following function called by the ALIAS MANAGER and the
00142 *   computation of SSA form.  The Aliased_Memop.... function
00143 *   examines the context and applies the enabled rules.
00144 *
00145 *   The rules are deliberately separated into two groups:  one that 
00146 *   is related to user-declaration, and the other to analyses.
00147 *   The user-declaration group is evaluated only once during SSA
00148 *   computations.  The analyses group is evalutated twice during SSA
00149 *   computations.
00150 *
00151 *   The flow is
00152 *     1) perform context-free alias analysis
00153 *     2) apply both declaration group and analyses group rule set.
00154 *     3) build SSA form
00155 *     4) perform context-sensitive alias analysis using the use-def
00156 *        chain provided by SSA.
00157 *     5) re-apply analyses group rules because of the extra information
00158 *        generated by context-sensitive analysis.
00159 *
00160 *
00161 *   BOOL Aliased_Memop_By_Analysis(const POINTS_TO *, const POINTS_TO *)
00162 *     Use the rules that based on flow-sensitive POINTS_TO analysis.
00163 *
00164 *   BOOL Aliased_Memop_By_Declaration(cosnt POINTS_TO *, const POINTS_TO *, TY *, TY*)
00165 *     Use the rules that based on language declarations.  
00166 *
00167 *   BOOL Aliased_Memop_By_Offset(cosnt POINTS_TO *, const POINTS_TO)
00168 *     Use only the offset rule because we know the base is the same.
00169 *
00170 *   BOOL Aliased_Memop(const POINTS_TO *, const POINTS_TO *)
00171 *     returns TRUE if two POINTS_TO are aliased.
00172 *     Invoke both Aliased_Memop_By_Analysis() and Aliased_Memop_By_Declaration().
00173 *
00174 *   BOOL Aliased_Memop(const POINTS_TO *, const POINTS_TO *, TY *, TY *)
00175 *     Same as Aliased_Memop(), but use the high level type information
00176 *     passed as parameter.
00177 *     Invoke both Aliased_Memop_By_Analysis() and Aliased_Memop_By_Declaration().
00178 *  
00179 *   BOOL Aliased_with_Call(ST *, const POINTS_TO *)
00180 *     Returns TRUE if the POINTS_TO is read/modified by the procedure call.
00181 *     
00182 *   BOOL Aliased_with_Region( ... )
00183 *      // to be implemented
00184 *
00185 *   BOOL Same_location(const WN *, const WN *, const POINTS_TO *, const POINTS_TO *)
00186 *      Two memory operations points to exactly the same location.
00187 *
00188 *   
00189 *   ALIAS RULES
00190 *   -----------
00191 *
00192 *   Rules applied to all languages.
00193 *
00194 *   A.1: (Base rule)
00195 *     Two memory operations are not aliased if their base is different.
00196 *     See opt_alias_analysis.h for the definition of  Same_base() 
00197 *     and Different_base().
00198 *
00199 *   A.2: (Ofst rule)
00200 *     Two memory operations are not aliased if their base is the same,
00201 *     and their memory ranges defined by the offset and size fields
00202 *     does not overlap.
00203 *
00204 *   A.3: (Nest_rule)
00205 *     Implementation not finished.  Supposed to deal with up-level references
00206 *     and nested procedures ...
00207 *
00208 *   A.4: (Indirect rule)
00209 *     Indirect memory access cannot access variables that are not address
00210 *     taken and saved.   See opt_alias_analysis.h for the definition
00211 *     of addr_taken_and_saved.
00212 *
00213 *   A.5: (Call_rule)
00214 *     A procedure call does not affect local variables that are not
00215 *     addr_taken_and_saved.
00216 *
00217 *   A.6: (Qual_rule)
00218 *     Use the qualified attributes.  
00219 *     WARNING: The Qual is physically distributed in different subroutines.
00220 *
00221 *     A.6.1: (pure funcition rule)
00222 *       Pure function is not aliased to any 
00223 *       memory operations. (See ST_pu_is_pure() in stab.h.)
00224 *
00225 *     A.6.2: (no side-effect function rule)
00226 *       No side-effect does not modify the value returned by any memory
00227 *       operations, but it might read the content of some memory.
00228 *       (See ST_pu_no_se(st) in stab.h.)
00229 *
00230 *     A.6.3: (const object)
00231 *        A const object is not modified.
00232 *
00233 *     A.6.4: (unique pointer)
00234 *       If a indirect memory operation has the unique_pt attribute,
00235 *       then the only memory operation that can alias to it is itself.
00236 *
00237 *
00238 *       
00239 *   C Rules
00240 *
00241 *   C.1: (ANSI Rules)
00242 *
00243 *     An object shall have its stored value accessed only by an lvalue that
00244 *     has one of the following types:
00245 *     *) the declared type of the object,
00246 *     *) a qualified version of the declared type of the object,
00247 *     *) a type that is signed or unsigned type corresponding to the declared type 
00248 *        of the object,
00249 *     *) a type that is signed or unisgined type corresponding to a 
00250 *        qualified version of the declared type of the object,
00251 *     *) an aggregrate or union type that includes one of the aforementioned types
00252 *        among its members (including, recursively, a member of a subaggregate 
00253 *        or contained union), 
00254 *     *) a character type, or
00255 *     *) a void type.
00256 *
00257 *     Use the Ragnarok interpretation here.  Objects are aliased if
00258 *     their base types (MTYPES), after stripping off the qualifiers and
00259 *     signed-ness, are equal.  See ANSI C 3.3 and 3.2.2.3.
00260 *
00261 *   C.2: (C Qualifier Rule)
00262 *
00263 *     C.2.1: (restricted pointer)
00264 *       If both memory operations are restricted pointer dereference,
00265 *       they are not aliased if their based pointer are different.
00266 *
00267 *
00268 *   C++ Rules
00269 *    Not determined.
00270 *
00271 *
00272 *   Fortran Rules
00273 *
00274 *   F.1: (Fortran Parameter rule)
00275 *     Fortran parameters are not aliased to anything except itself.
00276 *
00277 *   F.2: (Fortran Call rule)
00278 *      Fortran actual parameters can be modified.  Fortran calls have
00279 *      no side effect on address taken variables.
00280 *
00281 *   F.3: (Fortran pointer rule)
00282 *      // not implemented
00283 *      Fortran pointer-based variable cannot itself be a pointer.
00284 *
00285 *   F.4: (Fortran pointer restriction)
00286 *      // not implemented
00287 *      These restrictions are enforced by the frontend.
00288 *      A pointer-based variable cannot be used as a dummy argument or in 
00289 *      COMMON, EQUIVALENCE, DATA, or NAMELIST statements.
00290 *      The dimension expressions for pointer-based variables must be constant
00291 *      expressions in main programs. In subroutines and functions, the same rules
00292 *      apply for pointer-based variables as for dummy arguments. The expression
00293 *      can contain dummy arguments and variables in COMMON statements. Any
00294 *      variable in the expressions must be defined with an integer value at the
00295 *      time the subroutine or function is called.
00296 *
00297 *   
00298 *   Old Rules
00299 *
00300 *   O.1: (Ragnarok unnamed)
00301 *       Direct memory operations are not aliased to indirect memory operations.
00302 *
00303 *   O.2: (Ragnarok restricted)
00304 *       Memory operations are not aliased if their based pointer
00305 *       are different.
00306 *
00307 *
00308 * ======================================================================== 
00309 */
00310  
00311 
00312 
00313 class OPT_STAB;
00314 class AUX_STAB_ENTRY;
00315 class POINTS_TO;
00316 class WN;
00317 typedef struct bs BS;
00318 
00319 #include "optimizer.h"
00320 
00321 
00322 //  Assign a bitpos to each rule.
00323 //  _context in ALIAS_RULE control which rules can be applied
00324 //
00325 enum {
00326   // Rules common to all languages
00327   BASE_RULE = 0x1,
00328   OFST_RULE = 0x2,
00329   NEST_RULE = 0x4,
00330   INDR_RULE = 0x8,
00331   CALL_RULE = 0x10,
00332   QUAL_RULE = 0x20,
00333   ATTR_RULE = 0x40,
00334   CLAS_RULE = 0x80,
00335   IP_CLAS_RULE = 0x80000000,
00336   ALL_COMMON_RULES = 0x800000ff,
00337   DEFAULT_COMMON_RULES = 0x800000ff,
00338 
00339   // C Rules
00340   C_ANSI_RULE = 0x100,
00341   C_QUAL_RULE = 0x200,
00342   C_RESTRICT_CONST_RULE = 0x400,
00343   C_STRONGLY_TYPED_RULE = 0x800,
00344   ALL_C_RULES = 0x0f00,
00345   DEFAULT_C_RULES = 0x0200,
00346 
00347   // C++ Rules
00348   ALL_CXX_RULES = 0xf000,
00349   DEFAULT_CXX_RULES = 0xf000,
00350 
00351   // Fortran Rules
00352   F_PARM_RULE = 0x10000,
00353   F_CALL_RULE = 0x20000,
00354   F_CRAY_POINTER_RULE = 0x40000,
00355   ALL_F_RULES = 0x0f0000,
00356   DEFAULT_F_RULES = 0x020000,
00357 
00358   // F90 Rules
00359   F90_TARGET_RULE = 0x100000,
00360   ALL_F90_RULES = 0xf00000,
00361   DEFAULT_F90_RULES = 0xf00000,
00362 
00363   // Analysis Rules 
00364   FFA_RULE = 0x1000000,
00365   FSA_RULE = 0x2000000,
00366   ALL_ANALYSIS_RULES =  0x7000000,
00367   DEFAULT_ANALYSIS_RULES = 0x7000000,
00368 
00369   // Compatiability Rules
00370   IBM_DISJOINT_RULE =   0x08000000,
00371   RAG_RESTRICTED_RULE = 0x10000000,
00372   RAG_UNNAMED_RULE  =   0x20000000,
00373   RAG_PARMS_RULE  =     0x40000000,
00374   ALL_COMPATIABILITY_RULES = 0x78000000,
00375   DEFAULT_COMPATIABILITY_RULES = 0
00376 };
00377 
00378 
00379 class ALIAS_RULE {
00380 
00381   ALIAS_CONTEXT _context;  // control which rules can be applied
00382   
00383 private:
00384   
00385   //  Obtain the basic type from TY
00386   INT32 Get_stripped_mtype(TY_IDX ty) const;
00387 
00388   //  This routine are used by alias analysis internally.
00389   //  Each function implements one of the alias rules.
00390   //  See doc/Mongoose/alias-analysis-design for more details.
00391   
00392   BOOL Aliased_Base_Rule(const POINTS_TO *, const POINTS_TO *) const;
00393   // BOOL Aliased_Ofst_Rule(const POINTS_TO *, const POINTS_TO *);  // exported
00394   BOOL Aliased_Static_Nest_Rule(const POINTS_TO *, const POINTS_TO *) const;
00395   BOOL Aliased_Classification_Rule(const POINTS_TO * const, 
00396                                    const POINTS_TO * const) const;
00397   BOOL Aliased_Ip_Classification_Rule(const POINTS_TO *const, 
00398                                       const POINTS_TO *const) const;
00399   BOOL Aliased_F_Param_Rule(const POINTS_TO *, const POINTS_TO *) const;
00400   BOOL Aliased_ANSI_Type_Rule(const POINTS_TO *, const POINTS_TO *, TY_IDX, TY_IDX) const;
00401   BOOL Aliased_Qualifier_Rule(const POINTS_TO *, const POINTS_TO *, TY_IDX , TY_IDX ) const;
00402   BOOL Aliased_Attribute_Rule(const POINTS_TO *, const POINTS_TO *) const;
00403   BOOL Aliased_C_Qualifier_Rule(const POINTS_TO *, const POINTS_TO *) const;
00404   BOOL Aliased_Ragnarok_Unnamed(const POINTS_TO *, const POINTS_TO *) const;
00405   BOOL Aliased_Ragnarok_Restrict(const POINTS_TO *, const POINTS_TO *) const;
00406   BOOL Aliased_Disjoint(const POINTS_TO *, const POINTS_TO *) const;
00407   BOOL Aliased_Indirect_Rule(const POINTS_TO *, const POINTS_TO *) const;
00408   BOOL Aliased_F90_Target_Rule(const POINTS_TO *const, 
00409                                const POINTS_TO *const,
00410                                TY_IDX , TY_IDX ) const;
00411   
00412 public:
00413 
00414   ALIAS_RULE(ALIAS_CONTEXT ac):_context(ac) {}
00415 
00416   BOOL Aliased_Strongly_Typed_Rule(TY_IDX , TY_IDX ) const;
00417 
00418   //  Check if a rule is applicable
00419   BOOL Rule_enabled(ALIAS_CONTEXT rule) const   {  return _context & rule; }
00420 
00421   //  Add all call-by-reference language here!!!
00422   BOOL Call_by_reference(void) const   { return Rule_enabled(F_CALL_RULE); }
00423 
00424   // Get/Set alias context.
00425   void Set_context(ALIAS_CONTEXT c)    { _context = c; }
00426   ALIAS_CONTEXT Get_context(void)      { return _context; }
00427 
00428   //  Two memory operations are referencing the same location.
00429   BOOL Same_location(const WN *, const WN *, const POINTS_TO *, const POINTS_TO *);
00430 
00431   //  Offset,size of two memop overlapped.
00432   BOOL Aliased_Ofst_Rule(const POINTS_TO *, const POINTS_TO *) const;
00433 
00434   //  Interface exported to the optimizer.
00435   //  We provide two sets of interface functions.
00436 
00437   //  The first set returns whether two memops are aliased.
00438   //
00439   BOOL Aliased_Memop(const POINTS_TO *, const POINTS_TO *) const;
00440   BOOL Aliased_Memop(const POINTS_TO *, const POINTS_TO *, TY_IDX , TY_IDX ) const;
00441   BOOL Aliased_Memop_By_Analysis(const POINTS_TO *, const POINTS_TO *) const;
00442   BOOL Aliased_Memop_By_Declaration(const POINTS_TO *, const POINTS_TO *, TY_IDX , TY_IDX ) const;
00443   BOOL Aliased_Memop_By_Offset(const POINTS_TO *, const POINTS_TO *) const;
00444 
00445   BOOL Aliased_with_Global(const POINTS_TO *) const;
00446   BOOL Aliased_with_Indirect(const POINTS_TO *) const;
00447 
00448   //   The second set returns whether a scalar is aliased by a CALL
00449   //
00450   READ_WRITE Aliased_with_Call(ST *, INT32, const POINTS_TO *) const;
00451   // READ_WRITE Aliased_with_Region(REGION *, const POINTS_TO *);
00452 
00453   READ_WRITE Aliased_with_Asm(const WN *, const POINTS_TO *) const;
00454   
00455   //  The third set returns a bitset representing the set of named
00456   //  scalars that are affected by the side effect (memop to symbol
00457   //  analysis). The set is a conservative estimate.
00458   //
00459   const BS *Alias_Set_Indirect(const OPT_STAB *) const;
00460   const BS *Alias_Set_Call_By_Value(const OPT_STAB *) const;
00461   const BS *Alias_Set_Call_By_Ref(const OPT_STAB *) const;
00462   const BS *Alias_Set_Return(const OPT_STAB *) const;
00463   const BS *Alias_Set_Asm(const OPT_STAB *) const;
00464 };
00465 
00466 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines