Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
ipa_section.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 //* -*-Mode: c++;-*- (Tell emacs to use c++ mode) */
00037 #ifndef ipa_section_INCLUDED
00038 #define ipa_section_INCLUDED
00039 
00040 #ifdef IPA_SUMMARY
00041 #ifndef loop_info_INCLUDED
00042 #include "loop_info.h"
00043 #endif
00044 #ifndef cxx_hash_INCLUDED
00045 #include "cxx_hash.h"
00046 #endif
00047 #else
00048 
00049 #ifndef defs_INCLUDED
00050 #include "defs.h"
00051 #endif
00052 
00053 #ifndef wn_INCLUDED
00054 #include "wn.h"
00055 #endif
00056 
00057 #ifndef access_vector_INCLUDED
00058 #include "access_vector.h"
00059 #endif
00060 
00061 #ifndef cxx_memory_INCLUDED
00062 #include "cxx_memory.h"
00063 #endif
00064 
00065 #ifndef cxx_base_INCLUDED
00066 #include "cxx_base.h"
00067 #endif
00068 
00069 #ifndef opt_du_INCLUDED
00070 #include "optimizer.h"
00071 #endif
00072 
00073 #endif
00074 
00075 class IPA_LNO_READ_FILE; 
00076 
00077 extern BOOL Trace_Sections;
00078 // forward declarations:
00079 typedef STACK<INT> INT_ST;
00080 
00081 #define CONST_DESC 255
00082 
00083 // Sets that are being computed
00084 enum IPA_SECTION_TYPE {
00085   IPA_DEF = 1,
00086   IPA_USE = 2,
00087   IPA_REDUC = 3,
00088   IPA_PASS = 4,
00089   IPA_UNKNOWN = 5
00090 };
00091 
00092 // A term's variable, in a linear expression, can be one of:
00093 enum LTKIND {
00094   LTKIND_NONE,          // No term
00095   LTKIND_CONST,         // Constant
00096   LTKIND_LINDEX,        // One of the loop index variables
00097   LTKIND_SUBSCR,        // One of the array subscripts
00098   LTKIND_IV             // One of the independent variables
00099 };
00100 
00101 // when we set up the system of equations we need to specify the
00102 // action type
00103 enum ACTION_TYPE {
00104   ACTION_EQ,
00105   ACTION_LO,
00106   ACTION_UP
00107 };
00108 
00109 typedef mINT32 COEFF;       // A coefficient
00110 typedef mUINT16 DESCR;    // A coefficient descriptor
00111 
00112 
00113 //------------------------------------------------------------------------
00114 // node containing information about scalar symbols occuring in loops
00115 //------------------------------------------------------------------------
00116 class LOOP_SYMBOL
00117 {
00118 private:
00119   mUINT32 _ivar_index;
00120 
00121 public:
00122   LOOP_SYMBOL (UINT32 index) : 
00123     _ivar_index (index)
00124   {}
00125   
00126   BOOL operator== (const LOOP_SYMBOL& other) 
00127   {
00128     return (_ivar_index == other._ivar_index);
00129   }
00130   
00131   UINT32 Ivar_Index () const { return _ivar_index; }
00132   
00133   void Print (FILE* fp) { fprintf(fp, "IVAR[%d]\n", _ivar_index); }
00134 };
00135 
00136 typedef DYN_ARRAY<LOOP_SYMBOL> LOOP_SYMBOL_ARRAY;
00137 
00138 
00139 
00140 //===================================================================
00141 // In IPL and IPA, an IVAR represents either a formal parameter
00142 // (specified by its position) or a global variable (ST_IDX).
00143 // In LNO, an IVAR may also represent a local ST_IDX, when 
00144 // mapping a formal parameter into the actual argument
00145 //===================================================================
00146 class IVAR
00147 {
00148 private:
00149   union {
00150     mUINT32 _formal_position;
00151     ST_IDX  _st_idx;
00152   } u;
00153   
00154   WN_OFFSET _offset;
00155   mTYPE_ID  _mtype;
00156   mBOOL     _is_formal;
00157   
00158 public:
00159   IVAR (UINT32 position, WN_OFFSET offset, TYPE_ID mtype) 
00160   {
00161     u._formal_position = position;
00162     _offset = offset;
00163     _mtype = mtype;
00164     _is_formal = TRUE;
00165   }
00166   
00167   IVAR (const ST* st, WN_OFFSET offset, TYPE_ID mtype) 
00168   {
00169     u._st_idx = ST_st_idx(st);
00170     _offset = offset;
00171     _mtype = mtype;
00172     _is_formal = FALSE;
00173   }
00174 
00175   IVAR ()
00176   {
00177     u._formal_position = 0;
00178     u._st_idx = ST_IDX_ZERO;
00179     _offset = 0;
00180     _mtype = 0;
00181     _is_formal = FALSE;
00182   }
00183 
00184   BOOL Is_Formal () const { return _is_formal; }
00185 
00186   UINT32 Formal_Position () const 
00187   { 
00188     FmtAssert(_is_formal, ("IVAR::Formal_Position(): IVAR is not a formal"));
00189     return u._formal_position;
00190   }
00191 
00192   void Set_Formal_Position(UINT32 formal_position) 
00193   { 
00194     _is_formal = TRUE; 
00195     u._formal_position = formal_position; 
00196   }
00197 
00198   ST_IDX St_Idx () const 
00199   { 
00200     FmtAssert(!_is_formal, ("IVAR::St_Idx(): IVAR is a formal"));
00201     return u._st_idx; 
00202   }
00203 
00204   WN_OFFSET Offset () const { return _offset; }
00205 
00206   void Set_Offset(WN_OFFSET offset) { _offset = offset; }
00207 
00208   TYPE_ID Mtype () const { return _mtype; }
00209 
00210   void Set_Mtype (TYPE_ID mtype) { _mtype = mtype; }
00211 
00212   BOOL operator== (const IVAR& other) const 
00213   { 
00214     return (_is_formal == other._is_formal &&
00215             _offset == other._offset &&
00216             _mtype == other._mtype &&
00217             ((_is_formal && u._formal_position == other.u._formal_position) ||
00218              (!_is_formal && u._st_idx == other.u._st_idx)));
00219   }
00220 
00221   void Set_St_Idx (ST_IDX new_st_idx) 
00222   { 
00223     _is_formal = FALSE; 
00224     u._st_idx = new_st_idx; 
00225   }
00226 
00227   void Print (FILE* fp = stderr);
00228 
00229   void WB_Print (FILE* fp, INT ivar_index);
00230 
00231   void IPA_LNO_Print_File (FILE* fp = stderr, INT ivar_index = -1);
00232 
00233   void IPA_LNO_Print (FILE* fp = stderr, 
00234                       IPA_LNO_READ_FILE* IPA_LNO_File = NULL);
00235 
00236 };
00237 
00238 typedef DYN_ARRAY<IVAR> IVAR_ARRAY;
00239 
00240 //===========================================================
00241 // Define a term of a linear expression
00242 //===========================================================
00243 class TERM
00244 {
00245 private:
00246   COEFF _coeff;
00247   DESCR _desc;
00248   LTKIND _kind : 8;
00249   mUINT8 _projected_level;
00250 
00251 public:
00252   // constructors
00253   TERM (LTKIND kind, COEFF coeff, DESCR descr, mUINT8 level) :
00254     _coeff (coeff),
00255     _desc (descr),
00256     _kind (kind),
00257     _projected_level (level)
00258   {}
00259   
00260   TERM (const TERM* term) :
00261     _coeff (term->_coeff),
00262     _desc (term->_desc),
00263     _kind (term->_kind),
00264     _projected_level (term->_projected_level)
00265   {}
00266   
00267   void Set_coeff (COEFF w) { _coeff = w; }
00268   COEFF Get_coeff () const { return _coeff; }
00269 
00270   void Set_desc (DESCR b) { _desc = b; }
00271   DESCR Get_desc () const { return _desc; }
00272 
00273   void Set_type (LTKIND kind) { _kind = kind; }
00274   LTKIND Get_type () const    { return _kind; }
00275   
00276   void Set_projected_level (mUINT8 level) { _projected_level = level; }
00277   mUINT8 Get_projected_level () const     { return _projected_level; }
00278 
00279   BOOL Equivalent(TERM& t);
00280 
00281   BOOL Is_equal(TERM* t, INT count);
00282 
00283   void Print(FILE* fp = stderr, BOOL newline = TRUE);
00284 
00285   void Print_file(FILE* fp = stderr);
00286 
00287   void IPA_LNO_Print(FILE* fp = stderr, IPA_LNO_READ_FILE* ilr_file = NULL);
00288 
00289   void IPA_LNO_Print_File(FILE* fp = stderr, INT term_index = -1);
00290 
00291   void WB_Print(FILE* fp, INT term_index);
00292 };
00293 
00294 typedef DYN_ARRAY<TERM> TERM_ARRAY;
00295 
00296 // forward declaration
00297 class LOOPINFO;
00298 
00299 //===================================================================
00300 // an array of TERMS in a linear expression 
00301 //===================================================================
00302 class LINEX 
00303 {
00304 private:
00305   TERM_ARRAY _larray;
00306 
00307 public:
00308   // constructor
00309   LINEX (MEM_POOL* m) { new (&_larray) TERM_ARRAY(m); }
00310 
00311   // destructor
00312   ~LINEX () { _larray.Free_array(); }
00313   
00314 
00315   mINT32 Num_terms () const { return _larray.Lastidx(); }
00316 
00317   TERM* Get_term(INT32 idx) const { return &(_larray)[idx]; }
00318 
00319   void Set_term(const TERM* term) { _larray.AddElement(TERM(term)); }
00320   
00321   void Set_term(LTKIND kind, COEFF coeff, DESCR descr, mUINT8 level) 
00322   {
00323     _larray.AddElement(TERM(kind, coeff, descr, level));
00324   }
00325 
00326   void Set_linex_terms(INT start_index, INT end_index, TERM* term);
00327 
00328   // return the constant term 
00329   INT Get_constant_term();
00330   
00331   // copy a linex class
00332   void Copy(LINEX *to);
00333 
00334   // check if the coeff of the loop terms are equal
00335   BOOL Loop_coeff_terms_equal(LINEX* l);
00336 
00337   // check the number of loop coefficient terms
00338   INT Num_loop_coeff_terms();
00339 
00340   // check if the linear expression contains a term with
00341   // the loop coefficient "i" in it
00342   BOOL Has_loop_coeff(INT i);
00343   
00344   // map a linex expression to a vector in the systems of equations
00345   void Add_access(SYSTEM_OF_EQUATIONS *soe,
00346                   mUINT8 depth, 
00347                   INT num_dim, 
00348                   INT axle,
00349                   INT num_syms, 
00350                   ACTION_TYPE act, 
00351                   LOOP_SYMBOL_ARRAY* sym, 
00352                   BOOL trace);
00353   
00354   void Print(FILE* fp = stderr);
00355   void Print_file(FILE* fp = stderr);
00356 
00357   void Map_access_vector(ACCESS_VECTOR* av, BOOL Is_LNO, 
00358     IPA_LNO_READ_FILE* IPA_LNO_File);
00359 
00360   // map a particular line of an SOE to a linex
00361   void Map_from_SOE(const SYSTEM_OF_EQUATIONS* soe, 
00362                     INT i, 
00363                     const LOOP_SYMBOL_ARRAY* syms, 
00364                     INT depth, 
00365                     INT dim, 
00366                     INT which_array, 
00367                     BOOL is_lower_bound);
00368 
00369 
00370   // clean up the terms in the linex
00371   void Free_terms();
00372 
00373   BOOL Equivalent(LINEX &b);
00374 
00375   // compute the max, note, this is only valid if 
00376   INT Max(LINEX*l);
00377 
00378   // check if the linex  is a constant term only 
00379   // (used for step calculation)
00380   BOOL Is_const();
00381 
00382   // Merge/Add 2 linex terms
00383   LINEX* Merge(LINEX* l);
00384 
00385   // Subtract 2 linex terms
00386   LINEX* Subtract(LINEX* l);
00387 
00388   void Init(MEM_POOL* m);
00389 
00390   void Add_coupled_terms(LINEX* from);
00391 
00392   void Simplify();
00393   void LNO_Simplify(IPA_LNO_READ_FILE* IPA_LNO_File, WN* wn_call); 
00394   void Substitute_Lindex(INT lindex, LINEX* lx_substitute);
00395   void Remove_Zero_Terms();
00396   BOOL Has_Local_Symbol();
00397 };
00398 
00399 typedef DYN_ARRAY<LINEX> LINEX_ARRAY;
00400 
00401 class PROJECTED_KERNEL;
00402 typedef DYN_ARRAY<PROJECTED_KERNEL> PROJECTED_KERNEL_ARRAY;
00403 #ifdef IPA_SUMMARY
00404 extern IVAR_ARRAY *Ivar;
00405 
00406 // Mapping from LOOPINFO (ipl) to DO_LOOP_INFO_BASE (lno)
00407 typedef 
00408 HASH_TABLE<LOOPINFO*,DO_LOOP_INFO_BASE*> LOOPINFO_TO_DLI_MAP;
00409 extern LOOPINFO_TO_DLI_MAP* IPL_Loopinfo_Map;
00410 
00411 // Mapping from PROJECTED_REGION (ipl) to ACCESS_ARRAY (lno)
00412 class PROJECTED_REGION;
00413 typedef 
00414 HASH_TABLE<PROJECTED_REGION*,ACCESS_ARRAY*> PROJ_REGION_TO_ACCESS_ARRAY_MAP;
00415 extern PROJ_REGION_TO_ACCESS_ARRAY_MAP* IPL_Access_Array_Map;
00416 
00417 #endif 
00418 // ====================================================================
00419 //
00420 // LOOPINFO
00421 //
00422 // A loop nest, containing information about the nest itself, plus
00423 // common data structure elements for the array sections which occur
00424 // in the nest.
00425 //
00426 //
00427 // ====================================================================
00428 class LOOPINFO
00429 {
00430 private:
00431 #define MESSY_UPPER_BOUND 0x01
00432 #define MESSY_LOWER_BOUND 0x02
00433 #define MESSY_STRIDE      0x04
00434 #define MESSY_BOUNDS      0x08
00435 #define MESSY_ANY_BOUNDS  0x0f
00436 
00437   mINT8 _nest_level;
00438   mINT8 _flags;
00439 
00440   MEM_POOL* _mem_pool;
00441 
00442   // kernels for this loop (only used when in memory)
00443   PROJECTED_KERNEL_ARRAY* _kernel;
00444 
00445   union {
00446     struct {
00447       LINEX* _upper_linex;
00448       LINEX* _lower_linex;
00449       LINEX* _step_linex;
00450       LOOP_SYMBOL_ARRAY* _symbols;    
00451       mINT16 _cd_idx;      // id into the control dependence structure
00452     } u3;
00453     struct {
00454       mINT16 _upper_index; 
00455       mINT16 _lower_index; 
00456       mINT16 _step_index;
00457       mUINT8 _upper_count;
00458       mUINT8 _lower_count;
00459       mUINT8 _step_count;
00460     } u2;
00461   } u1;
00462 
00463 public:
00464   // constructors
00465   LOOPINFO(MEM_POOL* m) { memset(this, '\0', sizeof(LOOPINFO)); _mem_pool = m; }
00466 
00467   LOOPINFO(MEM_POOL* m, INT32 cd_idx);
00468 
00469   MEM_POOL* Mem_Pool() const     { return _mem_pool; }
00470   void Set_Mem_Pool(MEM_POOL* m) { _mem_pool = m; }
00471 
00472   mINT8 Get_nest_level()  const    { return _nest_level; }
00473   void Set_nest_level(mINT8 level) { _nest_level = level; }
00474 
00475   mINT8 Get_flags() const { return _flags; }
00476   void Set_flags(mINT8 f) { _flags = f; }
00477 
00478   mINT16 Get_cd_idx() const { return u1.u3._cd_idx; };
00479   void Set_cd_idx(mINT16 cd_idx) { u1.u3._cd_idx = cd_idx;};
00480 
00481   LINEX* Get_upper_linex() const { return u1.u3._upper_linex; }
00482   LINEX* Get_lower_linex() const { return u1.u3._lower_linex; }
00483   LINEX* Get_step_linex()  const { return u1.u3._step_linex;  }
00484 
00485   mINT32 Get_ub_term_index()   const { return u1.u2._upper_index; }
00486   mINT32 Get_lb_term_index()   const { return u1.u2._lower_index; }
00487   mINT32 Get_step_term_index() const { return u1.u2._step_index;  }
00488   mUINT8 Get_ub_term_count()   const { return u1.u2._upper_count; }
00489   mUINT8 Get_lb_term_count()   const { return u1.u2._lower_count; }
00490   mUINT8 Get_step_term_count() const { return u1.u2._step_count;  }
00491 
00492   void Set_ub_term_index(mINT16 i)   { u1.u2._upper_index = i; }
00493   void Set_lb_term_index(mINT16 i)   { u1.u2._lower_index = i; }
00494   void Set_step_term_index(mINT16 i) { u1.u2._step_index  = i; }
00495   void Set_ub_term_count(mUINT8 i)   { u1.u2._upper_count = i; }
00496   void Set_lb_term_count(mUINT8 i)   { u1.u2._lower_count = i; }
00497   void Set_step_term_count(mUINT8 i) { u1.u2._step_count  = i; }
00498 
00499   BOOL Is_messy_ub()         const { return _flags & MESSY_UPPER_BOUND; }
00500   BOOL Is_messy_lb()         const { return _flags & MESSY_LOWER_BOUND; }
00501   BOOL Is_messy_step()       const { return _flags & MESSY_STRIDE; }
00502   BOOL Is_messy_bounds()     const { return _flags & MESSY_BOUNDS; }
00503   BOOL Is_messy_any_bounds() const { return _flags & MESSY_ANY_BOUNDS; }
00504 
00505   void Set_messy_ub ()    { _flags |= MESSY_UPPER_BOUND; }
00506   void Set_messy_lb()     { _flags |= MESSY_LOWER_BOUND; }
00507   void Set_messy_step()   { _flags |= MESSY_STRIDE; }
00508   void Set_messy_bounds() { _flags |= MESSY_ANY_BOUNDS; }
00509 
00510 #ifdef IPA_SUMMARY
00511   void Map_do_loop_info(DO_LOOP_INFO_BASE* dli);
00512 #endif
00513 
00514   void Create_linex(TERM* term);
00515 
00516   LINEX* Build_linex(ACCESS_VECTOR* av);
00517 
00518   PROJECTED_KERNEL_ARRAY* Get_kernels() const { return _kernel; }
00519 
00520   void Add_bound(LINEX* l, 
00521                  SYSTEM_OF_EQUATIONS* soe, 
00522                  mUINT8 depth, 
00523                  INT num_dim, 
00524                  INT num_syms, 
00525                  LOOP_SYMBOL_ARRAY* sym);
00526 
00527 
00528 
00529   void Print(FILE* fp = stderr);
00530   void Print_file(FILE* fp = stderr);
00531   void WB_Print(FILE* fp, INT loop_info_index);
00532 
00533   LOOP_SYMBOL_ARRAY*  Get_symbol_array() const { return u1.u3._symbols;};
00534 
00535   LINEX* Min_value();
00536   LINEX* Max_value();
00537 };
00538 
00539 typedef DYN_ARRAY<LOOPINFO> LOOPINFO_ARRAY;
00540 
00541 //------------------------------------------------------------------------
00542 // after a linex has been projected, we obtain upper, lower and step 
00543 // linex constraints
00544 // this is equivalent to the AXLE_NODE structure
00545 //------------------------------------------------------------------------
00546 class PROJECTED_NODE
00547 {
00548 private:
00549 #define MESSY_UPPER_BOUND 0x01
00550 #define MESSY_LOWER_BOUND 0x02
00551 #define MESSY_STRIDE      0x04
00552 #define UNPROJECTED       0x08
00553 #define ASSUMED_SHAPE     0x10
00554 
00555   union {
00556     struct {
00557       LINEX* _lb_linex;
00558       LINEX* _ub_linex;
00559       LINEX* _step_linex;
00560       LINEX* _segment_length_linex;
00561       LINEX* _segment_stride_linex;
00562     } u0;
00563     struct {
00564       mINT32  _lb_term_index : 24;
00565       mUINT32 _lb_term_count : 8;
00566       mINT32  _ub_term_index : 24;
00567       mUINT32 _ub_term_count : 8;
00568       mINT32  _step_term_index : 24;
00569       mUINT32 _step_term_count : 8;
00570       mINT32  _segment_length_term_index : 24;
00571       mUINT32 _segment_length_term_count : 8;
00572       mINT32  _segment_stride_term_index : 24;
00573       mUINT32 _segment_stride_term_count : 8;
00574     } u1;
00575   } u2;
00576 
00577   mUINT32 _flags;
00578   MEM_POOL* _mem_pool;
00579 
00580 public:
00581   void Init(MEM_POOL* m);
00582 
00583   void Set_Mem_Pool(MEM_POOL* mem_pool) { _mem_pool = mem_pool; }
00584   MEM_POOL* Mem_Pool() { return _mem_pool; }
00585 
00586   LINEX* Get_lower_linex() const { return (u2.u0._lb_linex); }
00587   void Set_lower_linex(LINEX* l) { u2.u0._lb_linex = l; }
00588 
00589   LINEX* Get_upper_linex()  const { return (u2.u0._ub_linex); }
00590   void Set_upper_linex(LINEX* l)  { u2.u0._ub_linex = l; }
00591 
00592   LINEX* Get_step_linex() const { return (u2.u0._step_linex); }
00593   void Set_step_linex(LINEX* l) { u2.u0._step_linex = l; }
00594 
00595   LINEX* Get_segment_length_linex() const { 
00596     return (u2.u0._segment_length_linex);
00597   }
00598   void Set_segment_length_linex(LINEX* l) { 
00599     u2.u0._segment_length_linex = l; 
00600   }
00601 
00602   LINEX* Get_segment_stride_linex() const { 
00603     return (u2.u0._segment_stride_linex);
00604   }
00605   void Set_segment_stride_linex(LINEX* l) { 
00606     u2.u0._segment_stride_linex = l; 
00607   }
00608 
00609   mINT32 Get_lb_term_index() const { return u2.u1._lb_term_index; }
00610   void Set_lb_term_index(mINT32 i) { u2.u1._lb_term_index = i; }
00611 
00612   mUINT32 Get_lb_term_count() const { return u2.u1._lb_term_count; }
00613   void Set_lb_term_count(mUINT32 i) { u2.u1._lb_term_count = i; }
00614 
00615   mINT32 Get_ub_term_index() const { return u2.u1._ub_term_index; }
00616   void Set_ub_term_index(mINT32 i) { u2.u1._ub_term_index = i; }
00617 
00618   mUINT32 Get_ub_term_count() const { return u2.u1._ub_term_count; }
00619   void Set_ub_term_count(mUINT32 i) { u2.u1._ub_term_count =i; }
00620 
00621   mINT32 Get_step_term_index() const { return u2.u1._step_term_index; }
00622   void Set_step_term_index(mINT32 i) { u2.u1._step_term_index=i; }
00623 
00624   mUINT32 Get_step_term_count() const { return u2.u1._step_term_count; }
00625   void Set_step_term_count(mUINT32 i) { u2.u1._step_term_count = i; }
00626 
00627   mINT32 Get_segment_length_term_index() const { 
00628     return u2.u1._segment_length_term_index; 
00629   }
00630   void Set_segment_length_term_index(mINT32 i) { 
00631     u2.u1._segment_length_term_index=i; 
00632   }
00633 
00634   mINT32 Get_segment_length_term_count() const { 
00635     return u2.u1._segment_length_term_count; 
00636   }
00637   void Set_segment_length_term_count(mINT32 i) { 
00638     u2.u1._segment_length_term_count=i; 
00639   }
00640 
00641   mINT32 Get_segment_stride_term_index() const { 
00642     return u2.u1._segment_stride_term_index; 
00643   }
00644   void Set_segment_stride_term_index(mINT32 i) { 
00645     u2.u1._segment_stride_term_index=i; 
00646   }
00647 
00648   mINT32 Get_segment_stride_term_count() const { 
00649     return u2.u1._segment_stride_term_count; 
00650   }
00651   void Set_segment_stride_term_count(mINT32 i) { 
00652     u2.u1._segment_stride_term_count=i; 
00653   }
00654 
00655   BOOL Is_messy_ub() const { return _flags & MESSY_UPPER_BOUND;}
00656   void Set_messy_ub()      { _flags |= MESSY_UPPER_BOUND; }
00657   
00658   BOOL Is_messy_lb() const { return _flags & MESSY_LOWER_BOUND; }
00659   void Set_messy_lb()      { _flags |= MESSY_LOWER_BOUND; }
00660   
00661   BOOL Is_messy_step() const { return _flags & MESSY_STRIDE; }
00662   void Set_messy_step()      { _flags |= MESSY_STRIDE; }
00663 
00664   BOOL Has_a_messy_bound() const 
00665   { return _flags & (MESSY_UPPER_BOUND | MESSY_LOWER_BOUND | MESSY_STRIDE); }
00666 
00667   BOOL Has_all_messy_bounds() const { 
00668     return ((_flags & MESSY_UPPER_BOUND) && 
00669             (_flags & MESSY_LOWER_BOUND) &&
00670             (_flags & MESSY_STRIDE));
00671   }
00672   
00673   void Set_all_messy_bounds() 
00674   {_flags |= (MESSY_UPPER_BOUND | MESSY_LOWER_BOUND | MESSY_STRIDE); }
00675   
00676   BOOL Is_unprojected() const { return _flags & UNPROJECTED; }
00677   void Set_unprojected()      { _flags |= UNPROJECTED; }
00678   void Reset_is_unprojected() { _flags &= ~UNPROJECTED; }
00679 
00680   BOOL Is_assumed_shape() const { return _flags & ASSUMED_SHAPE; }
00681   void Set_assumed_shape()      { _flags |= ASSUMED_SHAPE; }
00682 
00683   mUINT32 Get_flags() const     { return _flags; }
00684   void Set_flags(mUINT32 flags) { _flags = flags; }
00685 
00686 
00687   void Create_linex(TERM* t);
00688 
00689   // return the constant term in linex lower
00690   INT Get_constant_term();
00691 
00692   void Set_linexs(const SYSTEM_OF_EQUATIONS *soe,
00693                   INT i, 
00694                   INT j, 
00695                   const LOOP_SYMBOL_ARRAY *syms, 
00696                   INT depth,
00697                   INT dim,
00698                   INT stride);
00699 
00700   void Set_linexs(LINEX* low_new, 
00701                   LINEX* up_new,
00702                   LINEX* step_new,
00703                   LINEX* segment_length_new,
00704                   LINEX* segment_stride_new);
00705   
00706   void Set_linex_eq(const SYSTEM_OF_EQUATIONS *soe,
00707                     INT i, 
00708                     INT j, 
00709                     const LOOP_SYMBOL_ARRAY *syms,
00710                     INT depth, 
00711                     INT dim,
00712                     INT stride);
00713 
00714   void Set_linex_le(const SYSTEM_OF_EQUATIONS *soe,
00715                     INT i, 
00716                     INT j, 
00717                     const LOOP_SYMBOL_ARRAY *syms,
00718                     INT depth, 
00719                     INT dim,
00720                     INT stride);
00721 
00722   // set constant linexs for this projected node
00723   void Set_constant_linexs(INT32 upper, 
00724                            INT32 lower, 
00725                            INT32 step, 
00726                            INT32 segment_length, 
00727                            INT32 segment_stride);
00728   
00729   // Set linexes for a constant two-strided array section
00730   void Set_constant_two_strided_section(INT32 lower, 
00731                                         INT32 upper, 
00732                                         INT32 step, 
00733                                         INT32 seg_len,
00734                                         INT32 seg_stride);
00735 
00736   // reset the node fields, clear up all the terms
00737   void Reset_node();
00738 
00739   BOOL Equivalent( PROJECTED_NODE &b);
00740 
00741   // copy to 
00742   void Copy(PROJECTED_NODE *to);
00743 
00744   // print
00745   void Print(FILE *fp = stderr);
00746   void Print_file(FILE* fp = stderr);
00747   void IPA_LNO_Print(FILE *fp = stderr, 
00748                      IPA_LNO_READ_FILE* IPA_LNO_File = NULL);
00749   void IPA_LNO_Print_File(FILE *fp = stderr, INT pn_index = -1);
00750   void WB_Print(FILE* fp, INT proj_node_index);
00751 
00752   void Set_to_kernel_image(PROJECTED_NODE* pn_kernel, LINEX* lx_offset);
00753 
00754   void Fill_Out(); 
00755 
00756   void Simplify();
00757   void LNO_Simplify(IPA_LNO_READ_FILE* IPA_LNO_File, WN* wn_call);
00758   BOOL Matching_Segment_Stride(PROJECTED_NODE* pn);
00759 };
00760 
00761 typedef DYN_ARRAY<PROJECTED_NODE> PROJECTED_ARRAY;
00762 
00763 class PROJECTED_KERNEL;
00764 
00765 //------------------------------------------------------------------------
00766 // An array of projected nodes, one for each dimension of the array
00767 // this is equivalent to the REGION structure
00768 //------------------------------------------------------------------------
00769 class PROJECTED_REGION
00770 {
00771 private:
00772 #define MESSY_REGION 1
00773 #define NON_MESSY_REGION 2
00774 #define UNPROJECTED_REGION 4
00775 #define IS_MAY_KILL 8
00776 #define IS_MAY_USE 16
00777 #define IS_PASSED 32
00778 #define IS_FORMAL 64
00779 
00780   union  {
00781     PROJECTED_ARRAY* _region;
00782     mINT32 _id;
00783   } u1;
00784 
00785   mINT16 _type;
00786   mUINT8 _num_dims;
00787   mUINT8 _depth;
00788 
00789   // this is an index into the linex kernel (if one exists), 
00790   // used for optimizing away the projection operation
00791   union {
00792     mINT32 _projected_kernel;
00793     PROJECTED_KERNEL *_p;
00794     struct {
00795         mINT16 _callsite_id;
00796         mINT16 _actual_id;
00797       } u22;
00798     } u2;
00799 
00800   MEM_POOL* _mem_pool; 
00801 
00802 public:
00803 
00804   PROJECTED_REGION(ACCESS_ARRAY* ar, 
00805                    MEM_POOL* mem_pool, 
00806                    LOOPINFO *loop, 
00807                    BOOL in_ipl = TRUE,
00808                    IPA_LNO_READ_FILE* IPA_LNO_File = NULL);
00809 
00810   PROJECTED_REGION(PROJECTED_REGION* p);
00811 
00812   PROJECTED_REGION(mINT16 type,
00813                    mUINT8 depth, 
00814                    mUINT8 num_dim, 
00815                    MEM_POOL* mem_pool);
00816   
00817 
00818   void Set_Mem_Pool(MEM_POOL* mem_pool) { _mem_pool = mem_pool; }
00819   MEM_POOL* Mem_Pool() { return _mem_pool; }
00820 
00821   void Set_callsite_id(INT16 id) { u2.u22._callsite_id = id;};
00822   INT16 Get_callsite_id() const { return u2.u22._callsite_id;};
00823 
00824   void Set_actual_id(INT16 id) { u2.u22._actual_id = id;};
00825   INT16 Get_actual_id() const { return u2.u22._actual_id;};
00826 
00827   void Set_id(INT32 i)  { u1._id = i;};
00828   INT32 Get_id() const { return u1._id;};
00829 
00830   void Set_type(mINT16 type) { _type = type;};
00831   mINT16 Get_type() const { return _type; };
00832 
00833   void Set_num_dims(mUINT8 num_dims) { _num_dims = num_dims;};
00834   mUINT8 Get_num_dims() const { return _num_dims;};
00835   
00836   void Set_depth(mUINT8 depth) { _depth = depth;};
00837   mUINT8 Get_depth() const { return _depth;};
00838 
00839   mINT32 Get_projected_kernel_id() const { return u2._projected_kernel;};
00840   void Set_projected_kernel_id(mINT32 id) { u2._projected_kernel = id; };
00841 
00842   PROJECTED_KERNEL* Get_projected_kernel() const { return u2._p;};
00843   void Set_projected_kernel(PROJECTED_KERNEL *p) { u2._p = p;};
00844   
00845   BOOL Is_unprojected_region() const { return _type &
00846                                        UNPROJECTED_REGION;};
00847   void Set_unprojected() { _type = _type | UNPROJECTED_REGION;};
00848 
00849   void Reset_is_unprojected() { _type = _type & ~UNPROJECTED_REGION;};
00850 
00851   BOOL Is_messy_region() const { return _type & MESSY_REGION;};
00852   void Set_messy_region() { _type = _type | MESSY_REGION;};
00853 
00854   void  Reset_messy_region() { _type = _type & ~MESSY_REGION;};
00855   
00856   BOOL Is_may_kill() const { return _type & IS_MAY_KILL;};
00857   void Set_is_may_kill() { _type = _type | IS_MAY_KILL;};
00858 
00859   BOOL Is_may_use() const { return _type & IS_MAY_USE;};
00860   void Set_is_may_use() { _type = _type | IS_MAY_USE;};
00861 
00862   BOOL Is_passed() const { return _type & IS_PASSED;};
00863   void Set_is_passed() { _type = _type | IS_PASSED;};
00864 
00865   BOOL Is_formal() const { return _type & IS_FORMAL;};
00866   void Set_is_formal() { _type = _type | IS_FORMAL;};
00867 
00868   void Set_projected_node(PROJECTED_NODE *node) {
00869     u1._region->AddElement(*node);
00870   }
00871   PROJECTED_NODE* Get_projected_node(INT i) { return &(*u1._region)[i]; }
00872 
00873   BOOL Has_Messy_Bounds();
00874   BOOL Has_Important_Messy_Bounds(); // don't count the "adjustable" dim
00875   void Set_Messy_If_Local_Symbol();
00876 
00877   void Copy_projected_node(PROJECTED_NODE* node);
00878   void Copy_write(PROJECTED_REGION *p_in);
00879   
00880   void Set_projected_array(PROJECTED_ARRAY* region) { u1._region = region; }
00881   PROJECTED_ARRAY* Get_projected_array() const      { return u1._region; }
00882 
00883 
00884   // compare 2 projected regions
00885   INT Compare(PROJECTED_REGION *b);
00886 
00887   LINEX_ARRAY* Map_to_linex_array();
00888 
00889   void Project(INT depth, LOOPINFO *l);
00890   PROJECTED_REGION *Union(PROJECTED_REGION &b, const LOOPINFO& l);
00891 
00892   BOOL May_Union(PROJECTED_REGION& b, BOOL trace);
00893 
00894   void Set_region(SYSTEM_OF_EQUATIONS *soe, 
00895                   LOOP_SYMBOL_ARRAY *syms, 
00896                   INT stride[], 
00897                   INT pivot_row,
00898                   INT pos, 
00899                   INT loop_step, 
00900                   INT projected_axle);
00901 
00902   BOOL Equivalent(PROJECTED_REGION* p);
00903 
00904   BOOL Constant_bounds(mUINT8 num_dims);
00905 
00906   void Print(FILE* fp = stderr);
00907   void Print_file(FILE* fp = stderr);
00908   void IPA_LNO_Print(FILE* fp = stderr, IPA_LNO_READ_FILE* 
00909     IPA_LNO_File = NULL);
00910   void IPA_LNO_Print_File(FILE* fp = stderr, INT pr_index = -1);
00911   void WB_Print(FILE* fp, INT proj_region_index);
00912 
00913   void Simplify();
00914   void LNO_Simplify(IPA_LNO_READ_FILE* IPA_LNO_File, WN* wn_call);
00915   void Fill_Out();
00916   BOOL Matching_Segment_Stride(PROJECTED_REGION* pr);
00917 };
00918 
00919 typedef DYN_ARRAY<PROJECTED_REGION> PROJECTED_REGION_ARRAY;
00920 
00921 //------------------------------------------------------------------------
00922 // A kernel is simply a projected region without the constant terms
00923 // This is used as an optimization to reduce the number of times a
00924 // system of equations is solved to eliminate variables during projection
00925 //------------------------------------------------------------------------
00926 class PROJECTED_KERNEL
00927 {
00928 private:
00929   #define PROJECTED 1
00930   #define MESSY_KERNEL 2
00931   LINEX_ARRAY* _array;
00932   BOOL     *_is_independent;
00933   mINT16 _projected_level;
00934   mUINT8 _depth;
00935   mUINT8 _type;
00936   LINEX_ARRAY* _difference; 
00937   union {
00938     PROJECTED_REGION *_region;
00939     INT _id;
00940   } u1;
00941   MEM_POOL* _mem_pool;
00942 
00943 public:
00944 
00945   void Set_Mem_Pool(MEM_POOL* mem_pool) { _mem_pool = mem_pool; }
00946   MEM_POOL* Mem_Pool() { return _mem_pool; }
00947 
00948   void Init(PROJECTED_REGION*, LOOPINFO*);
00949 
00950   BOOL Is_independent(mINT32 i) const { return _is_independent[i];};
00951   
00952   void Set_depth(mUINT8 depth) { _depth = depth;};
00953   mUINT8 Get_depth() const { return _depth;};
00954   
00955   void Set_projected_level(mINT16 level) 
00956     { _projected_level = level;};
00957 
00958   void Set_region(PROJECTED_REGION* r)  { u1._region = r;};
00959   PROJECTED_REGION* Get_region() const { return u1._region;};
00960 
00961   mINT16 Get_projected_level() { return _projected_level;};
00962   mINT16 Get_num_dims() { return _array->Lastidx()+1;};
00963 
00964   LINEX* Get_linex(INT32 i) { return &(*_array)[i]; };
00965 
00966   void Set_is_projected() { _type = _type | PROJECTED;};
00967   BOOL Is_projected() const {  return _type & PROJECTED;};
00968 
00969   void Set_messy_kernel() { _type = _type | MESSY_KERNEL;};
00970   BOOL Is_messy_kernel() const {  return _type & MESSY_KERNEL;};
00971   
00972   void Project(mUINT8 depth, LOOPINFO* loop); 
00973   void Print(FILE* fp = stderr);
00974 
00975   LINEX_ARRAY* Get_Difference() {return _difference;};
00976   LINEX* Get_Difference(INT i) 
00977     {return _difference != NULL && i <= _difference->Lastidx() 
00978       ? &(*_difference)[i] : NULL;}; 
00979   void Set_Difference(PROJECTED_REGION* pr); 
00980 };
00981 
00982 //===================================================================
00983 // store a pointer to the projected region
00984 //===================================================================
00985 class PROJECTED_REGION_INFO
00986 {
00987 private:
00988   PROJECTED_REGION *_p;
00989   
00990 public:
00991   void Set_projected_region(PROJECTED_REGION *p) { _p = p; };
00992   PROJECTED_REGION*
00993     Get_projected_region() { return _p;};
00994   void Print(FILE *fp = stderr);
00995 };
00996 
00997 typedef DYN_ARRAY<PROJECTED_REGION_INFO> PROJECTED_REGION_INFO_ARRAY;
00998 
00999 #define IPL_HAS_BAD_ALIAS 1
01000 #define IPL_IS_LOOP_INVARIANT 2
01001 #define IPL_IS_DEF 4 // is it a definition?
01002 #define IPL_IS_USE 8 // is it a use?
01003 #define IPL_IS_PASSED 16 // is is passed?
01004 #define IPL_IS_MAY_USE 32  // may be used
01005 #define IPL_IS_MAY_DEF 64 // may be defined
01006 #define IPL_IS_FORMAL 128 // is a formal parameter
01007 
01008 //===================================================================
01009 // equivalent to ARA_REF in LNO's code
01010 //===================================================================
01011 class REGION_ARRAYS
01012 {
01013 private:
01014   mUINT8 _type;
01015   mINT32 _sym_index;
01016   mINT32 _element_size;
01017 
01018   union {
01019     PROJECTED_REGION_INFO_ARRAY *_regions;
01020     struct {
01021       mINT32 _idx; // index into the PROJECTED_REGION array
01022       mINT32 _count; // count of the elements in the PROJECTED_REGION array
01023     } u2;
01024   } u1;
01025 
01026 public:
01027   REGION_ARRAYS(MEM_POOL *m, mINT32 index) {
01028     u1._regions = (PROJECTED_REGION_INFO_ARRAY*) 
01029       CXX_NEW(PROJECTED_REGION_INFO_ARRAY(m),m);
01030     _type = 0;
01031     _sym_index  = index;
01032   }
01033 
01034   void Set_type(mUINT8 t ) { _type = t;};
01035   mUINT8 Get_type() const { return _type;};
01036 
01037   void Init(mINT32 index, mINT32 element_size, MEM_POOL *m);
01038 
01039   void Copy_write(REGION_ARRAYS *r);
01040 
01041   PROJECTED_REGION_INFO_ARRAY*
01042     Get_projected_region_array() const { return u1._regions; };
01043   
01044   void Set_has_bad_alias() { _type = _type | IPL_HAS_BAD_ALIAS;};
01045   BOOL Is_bad_alias() const { return _type & IPL_HAS_BAD_ALIAS ;};
01046 
01047   void Set_is_loop_invariant() { _type = _type |
01048                                    IPL_IS_LOOP_INVARIANT;};
01049   BOOL Is_loop_invariant() const { return _type & IPL_IS_LOOP_INVARIANT;};
01050 
01051   void Set_is_use() { _type = _type | IPL_IS_USE;}; 
01052   BOOL Is_use() const { return _type & IPL_IS_USE;};
01053 
01054   void Set_is_def() { _type = _type | IPL_IS_DEF;};
01055   BOOL Is_def() const { return _type & IPL_IS_DEF;};
01056 
01057   void Set_is_passed() { _type = _type | IPL_IS_PASSED;};
01058   BOOL Is_passed() const { return _type & IPL_IS_PASSED;};
01059 
01060   void Set_is_may_def() { _type = _type | IPL_IS_MAY_DEF;};
01061   BOOL Is_may_def() const { return _type & IPL_IS_MAY_DEF;};
01062 
01063   void Set_is_may_use() { _type = _type | IPL_IS_MAY_USE;};
01064   BOOL Is_may_use() const { return _type & IPL_IS_MAY_USE;};
01065 
01066   void Set_is_formal() { _type = _type | IPL_IS_FORMAL;};
01067   BOOL Is_formal() const { return _type & IPL_IS_FORMAL;};
01068 
01069   mINT32 Get_sym_id() const { return _sym_index;};
01070   void Set_sym_id(INT id) { _sym_index = id;};   
01071 
01072   mINT32 Get_element_size() const {return _element_size;};
01073   void Set_element_size(mINT32 element_size) {_element_size = element_size;};
01074 
01075   // this is an index into the projected region array
01076   mINT32 Get_idx() const { return u1.u2._idx;};
01077   void   Set_idx(mINT32 id) { u1.u2._idx = id; };
01078 
01079   // this is a count of the number of elements in the projected
01080   // region array
01081   mINT32 Get_count() const { return u1.u2._count; };
01082   void Set_count(mINT32 count) { u1.u2._count = count;};
01083 
01084   PROJECTED_REGION*
01085     Get_Projected_Region(INT i);
01086 
01087 
01088   void Print(FILE *fp = stderr);
01089   void Print_file(FILE* fp = stderr);
01090   void WB_Print(FILE* fp, INT region_index, char* name, char* func_name);
01091 };
01092 
01093 typedef DYN_ARRAY<REGION_ARRAYS> ARRAY_OF_REGION_ARRAYS;
01094 // typedef DYN_ARRAY<INT>  INT_ARRAY;
01095 
01096 #define IPA_SCALAR_MAY_KILL 1
01097 #define IPA_SCALAR_MAY_USE 2
01098 #define IPA_SCALAR_MAY_REDUC 4
01099 #define IPA_SCALAR_KILL 8
01100 #define IPA_SCALAR_USE 16
01101 #define IPA_SCALAR_REDUC 32
01102 #define IPA_ARRAY_REDUC 64
01103 #define IPA_ARRAY_MAY_REDUC 128
01104 #define IPA_SCALAR_PASSED 256
01105 #define IPA_SCALAR_EUSE 512
01106 #define IPA_SCALAR_CALL_EUSE 1024
01107 #define IPA_SCALAR_MAY_PASS 2048
01108 class SCALAR_INFO
01109 {
01110 public:
01111   mINT32 _index; // index into the symbols array
01112   mINT16 _type;   // type information
01113   mINT16 _call_index; // index into the callsite array in the case
01114                       // that it has been passed as a reference parameter
01115 public:
01116   mINT32 Get_id() const { return _index;};
01117   void Set_id(mINT32 i) { _index = i;};
01118 
01119   mINT16 Get_type() const { return _type;};
01120   void Set_type(mINT16 t) {  _type = t;};
01121 
01122   void Set_callsite_id(mINT16 c) { _call_index = c;};
01123   mINT16 Get_callsite_id() const { return _call_index;};
01124 
01125   void Set_may_kill() { _type = _type | IPA_SCALAR_MAY_KILL;};
01126   BOOL Is_may_kill() const { return _type & IPA_SCALAR_MAY_KILL;};
01127 
01128   void Set_may_use() { _type = _type | IPA_SCALAR_MAY_USE;};
01129   BOOL Is_may_use() const { return _type & IPA_SCALAR_MAY_USE;};
01130   
01131   void Set_may_reduc() { _type = _type | IPA_SCALAR_MAY_REDUC;};
01132   BOOL Is_may_reduc() const { return _type & IPA_SCALAR_MAY_REDUC;};
01133 
01134   void Set_kill() { _type = _type | IPA_SCALAR_KILL;};
01135   BOOL Is_kill() const { return _type & IPA_SCALAR_KILL;};
01136   
01137   void Set_use() { _type = _type | IPA_SCALAR_USE;};
01138   BOOL Is_use() const { return _type & IPA_SCALAR_USE;};
01139   
01140   void Set_euse() { _type = _type | IPA_SCALAR_EUSE;};
01141   BOOL Is_euse() const { return  _type  & IPA_SCALAR_EUSE;};
01142 
01143   void Set_call_euse() { _type = _type | IPA_SCALAR_CALL_EUSE;};
01144   BOOL Is_call_euse() const { return  _type & IPA_SCALAR_CALL_EUSE;};
01145  
01146   void Set_reduc() { _type = _type | IPA_SCALAR_REDUC;};
01147   BOOL Is_reduc() const { return _type & IPA_SCALAR_REDUC;};
01148 
01149   void Set_array_reduc() { _type = _type | IPA_ARRAY_REDUC;};
01150   BOOL Is_array_reduc() const { return _type & IPA_ARRAY_REDUC;};
01151 
01152   void Set_array_may_reduc() { _type = _type | IPA_ARRAY_MAY_REDUC;};
01153   BOOL Is_array_may_reduc() const { return _type & IPA_ARRAY_MAY_REDUC;};
01154 
01155   void Set_passed_ref() { _type = _type | IPA_SCALAR_PASSED;};
01156   BOOL Is_passed_ref() const { return _type & IPA_SCALAR_PASSED;};
01157 
01158   void Set_may_passed_ref() { _type = _type | IPA_SCALAR_MAY_PASS;};
01159   BOOL Is_may_passed_ref() const { return _type & IPA_SCALAR_MAY_PASS;};
01160   
01161   SCALAR_INFO () { _type = 0; _call_index =-1; _index = 0;};
01162   void Init() { _type =0; _call_index = -1; _index =0; };
01163 
01164   void Print_file(FILE *fp = stderr);
01165   void Print(FILE *fp = stderr) { Print_file(fp); };
01166   void WB_Print(FILE* fp, INT scalar_index, char* name, char* func_name);
01167 };
01168 
01169 typedef DYN_ARRAY<SCALAR_INFO> INT_ARRAY;
01170 
01171 
01172 //-------------------------------------------------------------------------
01173 // at each control flow node, attach the following sets:
01174 //-------------------------------------------------------------------------
01175 class CFG_NODE_INFO
01176 {
01177 private:
01178   union {
01179     ARRAY_OF_REGION_ARRAYS *_def;  // kill set of array regions
01180     mINT32 _def_index;             // index into region_arrays
01181   } u1;
01182   union {
01183     ARRAY_OF_REGION_ARRAYS *_use;  // upwardly exposed use set of array regions
01184     mINT32 _use_index;             // index into region_arrays
01185   } u2;
01186   union {
01187     ARRAY_OF_REGION_ARRAYS *_param;// array sections passed as actuals
01188     mINT32 _param_index;           // index into region_arrays
01189   } u3;
01190   union {
01191     INT_ARRAY *_scalar_info;       // kill set of scalars
01192     mINT32 _scalar_index;          // index into the scalar array
01193   } u4;
01194   union {
01195     LOOPINFO *_loop;               // loop node
01196     mINT32 _index;                 // index 
01197   } u5;
01198   union {
01199     ARRAY_OF_REGION_ARRAYS *_formal; // array sections for formals
01200     mINT32 _formal_index;            // index into region_arrays
01201   } u6;
01202 
01203   mINT16 _def_count;               // number of array regions in kill set
01204   mINT16 _use_count;               // number of array regions in euse set
01205   mINT16 _param_count;             // number of array regions in param set
01206   mINT16 _scalar_count;            // number of scalars
01207   mINT16 _formal_count;            // number of formals
01208 
01209   enum _cfg_type {
01210     CFG_IF      = 1,
01211     CFG_DO_LOOP = 2,
01212     CFG_ENTRY   = 3,
01213     CFG_ELSE    = 4,
01214     CFG_UNKNOWN = 5
01215   } _type : 4;
01216 
01217   enum _cfg_state {
01218     CFG_STATE_CLEAR = 0x0,
01219     CFG_HAS_CALLS   = 0x1,
01220     CFG_IS_EXECUTED = 0x2 // this is to be used for do loops, i.e. are
01221                            // they definitely executed? if yes then we
01222                            // need to take that into account when
01223                            // computing kill information for instance
01224   } _state : 4;
01225 
01226   mINT32 _cd_index : 24;   // control dependence index (-1 for else nodes)
01227 
01228 public:
01229 
01230 #if 0
01231   void Set_type(enum cfg_type t) { _type = t;};
01232   enum cfg_type Get_type() { return _type;};
01233 #endif
01234   void Set_type_if()      { _type = CFG_IF; }
01235   void Set_type_do_loop() { _type = CFG_DO_LOOP; }
01236   void Set_type_entry()   { _type = CFG_ENTRY; }
01237   void Set_type_else()    { _type = CFG_ELSE; }
01238 
01239   BOOL Is_if()      const { return _type == CFG_IF; }
01240   BOOL Is_do_loop() const { return _type == CFG_DO_LOOP; }
01241   BOOL Is_entry()   const { return _type == CFG_ENTRY; }
01242   BOOL Is_else()    const { return _type == CFG_ELSE; }
01243 
01244 #if 0
01245   void Set_state(mUINT8 s) { _state = s;};
01246   mUINT8 Get_state() const { return _state;};
01247 #endif
01248   void Set_has_calls()   { _state = (_cfg_state) (_state | CFG_HAS_CALLS); }
01249   void Set_is_executed() { _state = (_cfg_state) (_state | CFG_IS_EXECUTED); }
01250 
01251   BOOL Has_calls()   const { return _state & CFG_HAS_CALLS; }
01252   BOOL Is_executed() const { return _state & CFG_IS_EXECUTED; }
01253 
01254   void Set_cd_index(INT index) { _cd_index = index; }
01255   INT  Get_cd_index() const { return _cd_index; }
01256   
01257   CFG_NODE_INFO (MEM_POOL* m, INT16 index) { 
01258     u1._def = (ARRAY_OF_REGION_ARRAYS*)CXX_NEW(ARRAY_OF_REGION_ARRAYS(m), m);
01259     u2._use = (ARRAY_OF_REGION_ARRAYS*)CXX_NEW(ARRAY_OF_REGION_ARRAYS(m), m);
01260     u3._param = (ARRAY_OF_REGION_ARRAYS*)CXX_NEW(ARRAY_OF_REGION_ARRAYS(m), m);
01261     u4._scalar_info = (INT_ARRAY*)CXX_NEW(INT_ARRAY(m), m);
01262     u5._loop = (LOOPINFO*)CXX_NEW(LOOPINFO(m, index), m);
01263     u6._formal = (ARRAY_OF_REGION_ARRAYS*)CXX_NEW(ARRAY_OF_REGION_ARRAYS(m), m);
01264     _state = CFG_STATE_CLEAR;
01265     _type = CFG_UNKNOWN;
01266     _cd_index = -1;
01267   }
01268 
01269   void Init (MEM_POOL* m) { 
01270     u1._def = (ARRAY_OF_REGION_ARRAYS*)CXX_NEW(ARRAY_OF_REGION_ARRAYS(m), m);
01271     u2._use = (ARRAY_OF_REGION_ARRAYS*)CXX_NEW(ARRAY_OF_REGION_ARRAYS(m), m);
01272     u3._param = (ARRAY_OF_REGION_ARRAYS*)CXX_NEW(ARRAY_OF_REGION_ARRAYS(m), m);
01273     u4._scalar_info = (INT_ARRAY*)CXX_NEW(INT_ARRAY(m), m);
01274     u5._loop = NULL;
01275     u6._formal = (ARRAY_OF_REGION_ARRAYS*)CXX_NEW(ARRAY_OF_REGION_ARRAYS(m), m);
01276     _state = CFG_STATE_CLEAR;
01277     _type = CFG_UNKNOWN;
01278     _cd_index = -1;
01279   }
01280 
01281   void Init_Out () { 
01282     memset(this, '\0', sizeof(CFG_NODE_INFO));
01283     _type = CFG_UNKNOWN;
01284   }
01285 
01286   void Add_array_param(PROJECTED_REGION *p, mINT32 sym_index,
01287                        mINT32 element_size, INT16 callsite_id, 
01288                        INT16 actual_id);
01289   void Add_formal_array(PROJECTED_REGION *p, mINT32 element_size,
01290                         mINT32 idx_symbol, mINT32 idx_formal);
01291   void Add_def_array(PROJECTED_REGION* p, mINT32 element_size, 
01292                         mINT32 sym_index);
01293   void Add_may_def_array(PROJECTED_REGION* p, mINT32 element_size,
01294                         mINT32 sym_index);
01295   void Add_use_array(PROJECTED_REGION* p, mINT32 element_size,
01296                         mINT32 sym_index);
01297   void Add_may_use_array(PROJECTED_REGION* p, mINT32 element_size,
01298                         mINT32 sym_index);
01299 
01300   void Add_scalar_def(mINT32 id);
01301   void Add_scalar_use(mINT32 id);
01302   void Add_scalar_reduc(mINT32 id);
01303   void Add_array_reduc(mINT32 id);
01304   void Add_array_may_reduc(mINT32 id);
01305   void Add_scalar_may_reduc(mINT32 id);
01306   void Add_scalar_may_def(mINT32 id);
01307   void Add_scalar_may_use(mINT32 id);
01308   INT Add_scalar_ref_passed(mINT32 id, mINT16 callsite_id);
01309   INT Add_scalar_ref_may_passed(mINT32 id, mINT16 callsite_id);
01310 
01311   ARRAY_OF_REGION_ARRAYS* Get_def_array() const { return u1._def; }
01312   ARRAY_OF_REGION_ARRAYS* Get_use_array() const { return u2._use; }
01313   ARRAY_OF_REGION_ARRAYS* Get_param_array() const { return u3._param; }
01314   ARRAY_OF_REGION_ARRAYS* Get_formal_array() const { return u6._formal; }
01315 
01316   INT_ARRAY* Get_scalar_array() const { return u4._scalar_info; }
01317   INT_ARRAY* Get_scalar_def_array() const { return u4._scalar_info; }
01318   INT_ARRAY* Get_scalar_use_array() const { return u4._scalar_info; }
01319   INT_ARRAY* Get_scalar_reduc_array() const { return u4._scalar_info; }
01320   INT_ARRAY* Get_array_reduc() const { return u4._scalar_info; }
01321 
01322   LOOPINFO *Get_loopinfo() const { return u5._loop; }
01323   void Set_loopinfo(LOOPINFO *l) { u5._loop = l; }
01324 
01325   void Print(FILE *fp = stderr);
01326   void Print_file(FILE *fp = stderr);
01327   void WB_Print(FILE* fp, INT cfg_index);
01328 
01329   // output related utils
01330   void Set_def_count(INT count) { _def_count = count; }
01331   void Set_def_index(INT index) {u1._def_index = index; }
01332 
01333   INT Get_def_count() const { return _def_count; }
01334   INT Get_def_index() const { return u1._def_index; }
01335 
01336   void Set_use_count(INT count) { _use_count = count; }
01337   void Set_use_index(INT index) { u2._use_index = index; }
01338 
01339   INT Get_use_count() const { return _use_count; }
01340   INT Get_use_index() const { return u2._use_index; }
01341 
01342   void Set_param_count(INT count) { _param_count = count; }
01343   void Set_param_index(INT index) { u3._param_index = index; }
01344 
01345   INT Get_param_count() const { return _param_count; }
01346   INT Get_param_index() const { return u3._param_index; }
01347 
01348   void Set_scalar_count(INT count) { _scalar_count = count; }
01349   void Set_scalar_index(INT index) { u4._scalar_index = index; }
01350 
01351   INT Get_scalar_count() const { return _scalar_count; }
01352   INT Get_scalar_index() const { return u4._scalar_index; }
01353 
01354   void Set_formal_count(INT count) { _formal_count = count; }
01355   void Set_formal_index(INT index) { u6._formal_index = index; }
01356 
01357   INT Get_formal_count() const { return _formal_count; }
01358   INT Get_formal_index() const { return u6._formal_index; }
01359 
01360   void Set_loop_index(INT index) { u5._index = index; }
01361   INT  Get_loop_index() const { return u5._index; }
01362 
01363   // used if the type of the cfg node is CFG_IF
01364   void Set_else_index(INT index) { 
01365     if (Is_if()) 
01366       u5._index = index;
01367     else
01368       Fail_FmtAssertion("Invalid type when setting else index for CFG_NODE\n");
01369   };
01370 
01371   INT Get_else_index() { 
01372     if (Is_if())
01373       return u5._index;
01374     else
01375       Fail_FmtAssertion("Invalid type when using Get else index for CFG_NODE");
01376     return -1;
01377   };
01378 
01379   // used if the type of the cfg node is CFG_ELSE
01380   void Set_if_index(INT index) { 
01381     if (Is_else()) 
01382       u5._index = index;
01383     else
01384       Fail_FmtAssertion("Invalid type when using Set_if_index for CFG_NODE");
01385   };
01386   
01387   // used if the type of the cfg node is CFG_IF
01388   INT Get_if_index()  {
01389     if (Is_else())
01390       return u5._index;
01391     else
01392       Fail_FmtAssertion("Invalid type when using Get_if_index for CFG_NODE");
01393     return -1;
01394   };
01395 
01396 };
01397 
01398 
01399 extern void Init_ivar_arrays();
01400 
01401 typedef DYN_ARRAY<CFG_NODE_INFO> CFG_NODE_INFO_ARRAY;
01402 
01403 //--------------------------------------------------------------------------
01404 // ids for mapping the scalar info ids in the summary actual nodes
01405 //--------------------------------------------------------------------------
01406 class INT_IDS
01407 {
01408 private:
01409   INT32 _id; 
01410   INT32 _cd_idx;
01411 
01412 public:
01413   INT32 Get_id() const { return _id;};
01414   void Set_id(INT32 i) { _id = i;};
01415 
01416   INT32 Get_cd_idx() const { return _cd_idx;};
01417   void Set_cd_idx(INT32 t) {  _cd_idx = t;};
01418 };
01419 
01420 //----------------------------------------------------------------------
01421 // construct the tlog information
01422 //----------------------------------------------------------------------
01423 class TLOG_INFO
01424 {
01425 private:
01426   INT _cterm_count, _lterm_count, _iv_g_term_count,  _iv_term_count;
01427   INT _sub_term_count;
01428 
01429 public:
01430   TLOG_INFO() { memset(this, '\0', sizeof(TLOG_INFO)); };
01431   INT& Get_cterm_count()  { return _cterm_count;};
01432   INT& Get_lterm_count()  { return _lterm_count;};
01433   INT& Get_iv_gterm_count()  { return _iv_g_term_count;};
01434   INT& Get_iv_term_count()  { return _iv_term_count;};
01435   INT& Get_sub_term_count() { return _sub_term_count;};
01436 
01437   void Set_cterm_count(INT count ) {_cterm_count = count;};
01438   void Set_lterm_count(INT count ) {_lterm_count = count;};
01439   void Set_iv_gterm_count(INT count) {_iv_g_term_count = count;};
01440   void Set_iv_term_count(INT count ) {_iv_term_count = count;};
01441   void Set_sub_term_count(INT count ) {_sub_term_count = count;};
01442  
01443 };
01444 
01445 //--------------------------------------------------------------------------
01446 // array section summary information 
01447 //--------------------------------------------------------------------------
01448 class ARRAY_SUMMARY
01449 {
01450 private:
01451   MEM_POOL _array_pool;
01452   MEM_POOL _local_array_pool;
01453   MEM_POOL _write_pool;
01454   IVAR_ARRAY *_ivar;
01455   TERM_ARRAY *_term_array;
01456   PROJECTED_ARRAY *_project_nodes;
01457   PROJECTED_REGION_ARRAY *_projected_regions;
01458   ARRAY_OF_REGION_ARRAYS *_region_arrays;
01459   CFG_NODE_INFO_ARRAY *_cfg_nodes;
01460   LOOPINFO_ARRAY *_loop_nodes;
01461   INT_IDS *_actual_scalar_info_map;
01462   INT *_cd_map; // map the cd index to the "real cd index"
01463   INT _formal_start_idx;
01464   INT _formal_count;
01465   INT  _actual_start_idx;
01466   INT _actual_count;
01467   INT  _callsite_start_idx;
01468   INT _callsite_count;
01469   TLOG_INFO *_tlog_info;
01470 
01471 public:
01472   void Init(INT formal_count, INT formal_idx, 
01473             INT actual_count, INT actual_idx,
01474             INT callsite_count, INT callsite_idx, 
01475             INT cd_size)
01476     {
01477       MEM_POOL_Initialize(&_array_pool, "array section pool", 0);
01478       MEM_POOL_Initialize(&_local_array_pool, "local array pool", 0);
01479       MEM_POOL_Initialize(&_write_pool, "write array pool", 0);
01480       MEM_POOL_Push(&_array_pool);
01481       MEM_POOL_Push(&_local_array_pool);
01482       MEM_POOL_Push(&_write_pool);
01483       _ivar = CXX_NEW(IVAR_ARRAY(&_write_pool), &_write_pool);
01484       _term_array = CXX_NEW(TERM_ARRAY(&_write_pool), &_write_pool);
01485       _project_nodes = CXX_NEW(PROJECTED_ARRAY(&_write_pool),
01486                                &_write_pool);
01487       _projected_regions =
01488         CXX_NEW(PROJECTED_REGION_ARRAY(&_write_pool), &_write_pool);
01489       _region_arrays =
01490         CXX_NEW(ARRAY_OF_REGION_ARRAYS(&_write_pool), &_write_pool);
01491       _cfg_nodes =
01492         CXX_NEW(CFG_NODE_INFO_ARRAY(&_write_pool), &_write_pool);
01493       _loop_nodes =
01494         CXX_NEW(LOOPINFO_ARRAY(&_write_pool), &_write_pool);
01495       _actual_scalar_info_map = (INT_IDS*)
01496         MEM_POOL_Alloc(&_write_pool, sizeof(INT_IDS)*(actual_count+1));
01497       _formal_start_idx = formal_idx;
01498       _formal_count = formal_count;
01499       _actual_start_idx = actual_idx;
01500       _actual_count = actual_count;
01501       _callsite_start_idx = callsite_idx;
01502       _callsite_count = callsite_count;
01503       memset(_actual_scalar_info_map, '\0', sizeof(INT_IDS)*(actual_count+1));
01504       if (cd_size)
01505         _cd_map = (INT*)
01506           MEM_POOL_Alloc(&_write_pool, sizeof(INT)*cd_size);
01507       _tlog_info = CXX_NEW(TLOG_INFO(), &_write_pool);;
01508       Init_ivar_arrays();
01509       //Set_Trace_Sections();
01510     };
01511 
01512   void Finalize() 
01513     {
01514       MEM_POOL_Pop(&_array_pool);
01515       MEM_POOL_Pop(&_local_array_pool);
01516       MEM_POOL_Pop(&_write_pool);
01517 
01518       MEM_POOL_Delete(&_array_pool);
01519       MEM_POOL_Delete(&_local_array_pool);
01520       MEM_POOL_Delete(&_write_pool);
01521     };
01522   
01523   MEM_POOL* Get_local_pool()  { return &_local_array_pool;};
01524   MEM_POOL* Get_array_pool()  { return &_array_pool;};
01525   MEM_POOL* Get_write_pool() { return &_write_pool;};
01526   
01527   IVAR_ARRAY* Get_ivar_array() const { return _ivar;};
01528   TERM_ARRAY* Get_term_array()  { return _term_array;};
01529   PROJECTED_ARRAY* Get_projected_array() 
01530     { return _project_nodes; };
01531   PROJECTED_REGION_ARRAY* Get_projected_region_array() 
01532     { return _projected_regions;};
01533   ARRAY_OF_REGION_ARRAYS* Get_region_array() 
01534     { return _region_arrays; };
01535   CFG_NODE_INFO_ARRAY *Get_cfg_node_array() 
01536     { return _cfg_nodes;};
01537   LOOPINFO_ARRAY *Get_loopinfo_array()
01538     { return _loop_nodes;};
01539 
01540   INT_IDS* Get_actual_scalar_info_map() { return _actual_scalar_info_map;};
01541 
01542   INT Get_actual_scalar_info_id(INT id) { 
01543     return _actual_scalar_info_map[id].Get_id();
01544   };
01545 
01546   INT Get_actual_scalar_info_cd_idx(INT id) {
01547     return _actual_scalar_info_map[id].Get_cd_idx();
01548   };
01549 
01550   void Set_actual_scalar_info_map(INT id, INT cd_idx, INT actual_id)  { 
01551     _actual_scalar_info_map[actual_id].Set_id(id);
01552     _actual_scalar_info_map[actual_id].Set_cd_idx(cd_idx);
01553   };
01554 
01555   INT* Get_cd_map() const { return _cd_map;};
01556   IVAR* Get_ivar_array(INT i);
01557   TERM* Get_term_array(INT i);
01558   PROJECTED_NODE* Get_projected_array(INT i);
01559   PROJECTED_REGION* Get_projected_region_array(INT i);
01560   REGION_ARRAYS* Get_region_array(INT i); 
01561   CFG_NODE_INFO *Get_cfg_node_array(INT i); 
01562   LOOPINFO *Get_loopinfo_array(INT i);
01563   TLOG_INFO* Get_tlog_info() const { return _tlog_info;};
01564 
01565   INT Get_ivar_array_count() const { return _ivar->Lastidx()+1;};
01566   INT Get_term_array_count()  const { return _term_array->Lastidx()+1;};
01567   INT Get_projected_array_count() const
01568     { return _project_nodes->Lastidx() + 1; };
01569   INT Get_projected_region_array_count()  const
01570     { return _projected_regions->Lastidx() + 1;};
01571   INT Get_region_array_count() const
01572     { return _region_arrays->Lastidx() + 1; };
01573   INT Get_cfg_node_array_count() const
01574     { return _cfg_nodes->Lastidx() + 1;};
01575   INT Get_loopinfo_array_count() const
01576     { return _loop_nodes->Lastidx() + 1;};
01577   INT Get_formal_start_idx() const
01578     { return _formal_start_idx;};
01579   INT Get_formal_count() const
01580     { return _formal_count;};
01581   INT Get_actual_start_idx() const
01582     { return _actual_start_idx;};
01583   INT Get_actual_count() const
01584     { return _actual_count;};
01585   INT Get_callsite_start_idx() const
01586     { return _callsite_start_idx;};
01587   INT Get_callsite_count() const
01588     { return _callsite_count;};
01589 
01590   void Record_tlogs(TERM_ARRAY* t, INT offset);
01591 };
01592 
01593 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines