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 // GRA Preference classes 00037 // 00038 // Description: 00039 // 00040 // We can remove register transfers between LRANGEs when the result and 00041 // the operand of the copy are assigned the same register. This module 00042 // provides a data structure that keeps track of sets of LRANGEs that we 00043 // would like to keep in the same register so that we can remove such 00044 // copies. It also provides routines for finding such preferences during 00045 // GRA_Create(). 00046 // 00047 // These are equivalence classes of LRANGEs, representing the benefit of 00048 // allocating the same register to each of a set of LRANGES. This has 00049 // two rather different applications: 00050 // 00051 // 1. We try to remove copies between COMPLEMENT and region LRANGEs 00052 // by unifying the preference classes whenever we see a copy 00053 // between these two types of LRANGEs. 00054 // 00055 // 2. We try to remove copies between dedicated LOCAL and COMPLEMENT 00056 // LRANGEs in much the same way. But we preallocate the register 00057 // to the LOCAL so it will be seen as a preference when the globals 00058 // in the equivalance class are allocated. 00059 // 00060 // As we find such copies, we union the preference classes of the operand 00061 // and result of the copy, thus we call such copies, "preferencing 00062 // copies". 00063 // 00064 // Besides being a set of LRANGEs, GRA_PREFs also contain a set of BBs, 00065 // used to keep track of the blocks in which copies from one member 00066 // LRANGE to another are made. This set is used during LRANGE splitting 00067 // in order to dettermine which of the two resulting LRANGEs should be in 00068 // the preference class (in some cases both can be though, of course the 00069 // same register cannot be used throughout the original LRANGE or it 00070 // would not have been split.) 00071 // 00072 // There is no need for us to keep track of the unallocated LRANGEs in a 00073 // preference class (though each of the LRANGEs in the preference class 00074 // can cheaply find the preference class.) As each element of the 00075 // preference class is allocated a register, it is added to a sequence 00076 // sorted by the count of frequency weighted prefrencing copies of which 00077 // the LRANGE is either an operand or a result. An iterator type is 00078 // provided for the allocated LRANGEs in a preference class in this 00079 // order. 00080 // 00082 00083 00084 // $Revision: 1.2 $ 00085 // $Date: 02/11/07 23:41:30-00:00 $ 00086 // $Author: fchow@keyresearch.com $ 00087 // $Source: /scratch/mee/2.4-65/kpro64-pending/be/cg/gra_mon/SCCS/s.gra_pref.h $ 00088 00089 00090 #ifndef GRA_PREFERENCE_INCLUDED 00091 #define GRA_PREFERENCE_INCLUDED 00092 00093 #ifndef GRA_PREFERENCE_RCS_ID 00094 #define GRA_PREFERENCE_RCS_ID 00095 #ifdef _KEEP_RCS_ID 00096 static char *gra_preference_rcs_id = "$Source: /scratch/mee/2.4-65/kpro64-pending/be/cg/gra_mon/SCCS/s.gra_pref.h $ $Revision: 1.2 $"; 00097 #endif 00098 #endif 00099 00100 #include "defs.h" 00101 #include "tn.h" 00102 #include "mempool.h" 00103 #include "gra_lrange.h" 00104 #include "lrange_list.h" 00105 #include "gra_bb.h" 00106 00107 // Represents an equivalence class of LRANGEs that would all like to be 00108 // allocated to the same register. 00109 class GRA_PREF { 00110 friend class GRA_PREF_MGR; 00111 friend class GRA_PREF_LRANGE_ITER; 00112 GRA_PREF* parent; // Union-find data structure 00113 INT32 count; // See Aho, Hopcroft & Ulman 00114 LRANGE_LIST* lranges; // Sorted by freq weighted # of pref 00115 // copies 00116 00117 void Make_Parent_Of(GRA_PREF *child) { 00118 // <this> and <child> must initially both be roots. If they are not 00119 // identical, make <this> be the parent of child. Union any 00120 // blocks_with_copies from <child> into <this>. Ditto any allocated 00121 // LRANGEs. 00122 child->parent = this; 00123 count += child->count; 00124 Is_True(child->lranges == NULL, 00125 ("Union of GRA preferences with some allocated LRANGES")); 00126 } 00127 GRA_PREF *Find(void); 00128 public: 00129 GRA_PREF(void) {} 00130 ~GRA_PREF(void) {} 00131 00132 void Allocate_LRANGE( LRANGE* lrange ); 00133 }; 00134 00135 // Use to iterate over the allocated LRANGEs in a GRA_PREF. 00136 class GRA_PREF_LRANGE_ITER { 00137 LRANGE_LIST* current; 00138 public: 00139 GRA_PREF_LRANGE_ITER(void) {} 00140 ~GRA_PREF_LRANGE_ITER(void) {} 00141 00142 void Init(GRA_PREF *pref) { 00143 // Prepare <iter> to iterate over the allocated LRANGEs in order 00144 // of the frequency weighted count of preferencing copies that 00145 // reference the LRANGEs (this frequency weighted count is stored 00146 // in the LRANGEs themselves and maintained by the LRANGE 00147 // module.) Special hack -- if <pref> is NULL, iteration doesn't 00148 // happen. This is useful because we use NULL as the value for 00149 // LRANGEs that aren't preferenced. 00150 if (pref == NULL) 00151 current = NULL; 00152 else current = pref->Find()->lranges; } 00153 BOOL Done(void) { return current == NULL; } 00154 LRANGE *Current(void) { return LRANGE_LIST_first(current); } 00155 void Step(void) { current = LRANGE_LIST_rest(current); } 00156 }; 00157 00158 00159 // Contains source and destination TNs for the copy that creates the 00160 // preferencing opportunity. 00161 class GRA_PREF_CAND { 00162 TN* source; // Source TN of the preferencing copy 00163 TN* dest; // Destination TN of the preferencing copy 00164 public: 00165 GRA_PREF_CAND(void) {} 00166 ~GRA_PREF_CAND(void) {} 00167 00168 TN *Source(void) { return source; } 00169 void Source_Set(TN *s) { source = s; } 00170 TN *Dest(void) { return dest; } 00171 void Dest_Set(TN *d) { dest = d; } 00172 }; 00173 00174 00175 // Contains miminmal liveness information for determining if a preference 00176 // is legal. 00177 class GRA_PREF_LIVE { 00178 INT last_def; // last definition of TN seen in BB 00179 INT num_defs; // number of definitions of TN in BB 00180 INT exposed_use; // true if exposed use of TN at top of BB 00181 public: 00182 GRA_PREF_LIVE(void) {} 00183 ~GRA_PREF_LIVE(void) {} 00184 00185 INT Last_Def(void) { return last_def; } 00186 void Last_Def_Set(INT i) { last_def = i; } 00187 INT Num_Defs(void) { return num_defs; } 00188 void Num_Defs_Set(INT i) { num_defs = i; } 00189 INT Exposed_Use(void) { return exposed_use; } 00190 void Exposed_Use_Set(INT i) { exposed_use = i; } 00191 }; 00192 00193 00194 class GRA_PREF_MGR { 00195 public: 00196 GRA_PREF_MGR(void) {} 00197 ~GRA_PREF_MGR(void) {} 00198 00199 GRA_PREF* Create(void) { // Create a new GRA_PREF. 00200 GRA_PREF* pref = TYPE_MEM_POOL_ALLOC(GRA_PREF,GRA_pool); 00201 pref->lranges = NULL; 00202 pref->parent = NULL; 00203 pref->count = 1; 00204 return pref; 00205 } 00206 GRA_PREF *UnionD(GRA_PREF *pref0, GRA_PREF *pref1); 00207 GRA_PREF_CAND* CAND_Create(TN* dest, TN* source, MEM_POOL* pool) { 00208 // Allocate and initialize a GRA_PREF_CAND node 00209 GRA_PREF_CAND* gpc = TYPE_MEM_POOL_ALLOC(GRA_PREF_CAND, pool); 00210 gpc->Source_Set(source); 00211 gpc->Dest_Set(dest); 00212 return gpc; 00213 } 00214 GRA_PREF_LIVE *LIVE_Create(MEM_POOL *pool) { 00215 // Create and initialize a GRA_PREF_LIVE node 00216 GRA_PREF_LIVE* gpl = TYPE_MEM_POOL_ALLOC(GRA_PREF_LIVE, pool); 00217 gpl->Last_Def_Set(0); 00218 gpl->Num_Defs_Set(0); 00219 gpl->Exposed_Use_Set(FALSE); 00220 return gpl; 00221 } 00222 }; 00223 00224 extern GRA_PREF_MGR gra_pref_mgr; 00225 00226 #endif
1.5.6