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 // GRA_REGION -- Region encapsulation 00038 // 00039 // Description: 00040 // 00041 // Implementation details for GRA_REGIONs. 00042 // 00044 00045 00046 // $Revision: 1.2 $ 00047 // $Date: 02/11/07 23:41:30-00:00 $ 00048 // $Author: fchow@keyresearch.com $ 00049 // $Source: /scratch/mee/2.4-65/kpro64-pending/be/cg/gra_mon/SCCS/s.gra_region.cxx $ 00050 00051 #ifdef USE_PCH 00052 #include "cg_pch.h" 00053 #endif // USE_PCH 00054 #pragma hdrstop 00055 00056 #ifdef _KEEP_RCS_ID 00057 static char *rcs_id = "$Source: /scratch/mee/2.4-65/kpro64-pending/be/cg/gra_mon/SCCS/s.gra_region.cxx $ $Revision: 1.2 $"; 00058 #endif 00059 00060 #include "defs.h" 00061 #include "cg.h" 00062 #include "register.h" 00063 #include "gra_bb.h" 00064 #include "gra_lrange.h" 00065 #include "gra_region.h" 00066 00067 GRA_REGION_MGR gra_region_mgr; 00068 00070 // Add <gbb> to the list of BBs associated with <region>. 00071 void 00072 GRA_REGION::Add_GBB( GRA_BB* gbb ) 00073 { 00074 if ( first_gbb != NULL ) 00075 last_gbb->Region_Next_Set(gbb); 00076 else first_gbb = gbb; 00077 00078 gbb->Region_Next_Set(NULL); 00079 last_gbb = gbb; 00080 00081 if (BB_call(gbb->Bb())) 00082 flags = (REGION_FLAG) (flags | REGION_FLAGS_has_call); 00083 } 00084 00086 // allocate the lrange subuniverses for a region. 00087 void 00088 GRA_REGION::Alloc_Subuniverses(void) 00089 { 00090 ISA_REGISTER_CLASS rc; 00091 INT subuniverse_size; 00092 00093 // Using the GTN universe size is probably way too conservative 00094 // Most likely, there will some in each class, and the ones in the 00095 // regions will be transparent to the complement. divide total 00096 // universe size by region count for each region. 00097 if (Rid() == Current_Rid) { 00098 subuniverse_size = GTN_UNIVERSE_size; 00099 } else { 00100 subuniverse_size = GTN_UNIVERSE_size / gra_region_mgr.Alloc_Count(); 00101 } 00102 if (subuniverse_size == 0) ++subuniverse_size; // don't want 0 00103 FOR_ALL_ISA_REGISTER_CLASS( rc ) { 00104 subuniverse[rc] = lrange_sub_mgr.Create(subuniverse_size); 00105 } 00106 } 00107 00109 // Add <lrange> to the appropriate subuniverse of <region>. 00110 void 00111 GRA_REGION::Add_LRANGE( LRANGE* lrange) 00112 { 00113 if ( lrange->Type() == LRANGE_TYPE_LOCAL ) 00114 local_subuniverse->Add(lrange); 00115 else subuniverse[lrange->Rc()]->Add(lrange); 00116 ++lrange_count[lrange->Rc()]; 00117 } 00118 00120 // Returns total number of cycles in all the scheduled BBs in the region 00121 INT32 00122 GRA_REGION::Cycle_Count(void) 00123 { 00124 GRA_REGION_GBB_ITER iter; 00125 INT32 result = 0; 00126 00127 for (iter.Init(this); ! iter.Done(); iter.Step() ) { 00128 GRA_BB* gbb = iter.Current(); 00129 result += OP_scycle(BB_last_op(gbb->Bb())); 00130 } 00131 return result; 00132 } 00133 00135 // initialize the fields in GRA_REGION_MGR; called at start of GRA 00136 void 00137 GRA_REGION_MGR::Initialize(void) 00138 { 00139 _first_prev_alloc_region = NULL; 00140 _complement_region_created = FALSE; 00141 _map = TYPE_MEM_POOL_ALLOC_N(GRA_REGION*, GRA_pool, Last_Region_Id() + 1); 00142 bzero(_map, sizeof(GRA_REGION*) * (Last_Region_Id() + 1)); 00143 _alloc_count = 0; 00144 } 00145 00147 // Region creation common to complement and previously allocate regions. 00148 GRA_REGION* 00149 GRA_REGION_MGR::Create( RID* rid) 00150 { 00151 ISA_REGISTER_CLASS rc; 00152 GRA_REGION* region = TYPE_MEM_POOL_ALLOC(GRA_REGION,GRA_pool); 00153 00154 _alloc_count++; 00155 00156 region->rid = rid; 00157 FOR_ALL_ISA_REGISTER_CLASS( rc ) { 00158 region->registers_used[rc] = REGISTER_SET_EMPTY_SET; 00159 region->registers_available[rc] = REGISTER_CLASS_allocatable(rc); 00160 region->lrange_count[rc] = 0; 00161 } 00162 00163 region->first_gbb = NULL; 00164 region->flags = (REGION_FLAG) 0; 00165 return region; 00166 } 00167 00169 GRA_REGION* 00170 GRA_REGION_MGR::Create_Complement( RID* rid ) 00171 { 00172 GRA_REGION* region = Create(rid); 00173 00174 // This is a totally wild guess of the number of local live ranges 00175 // we'll need. But an average of 10/BB doesn't seem too bad. It's 00176 // probably high because we are counting the BBs in the regions as well 00177 // and there are probably less than 10 on average. However, 00178 // it just has to prevent some worst case behavior. 00179 region->local_subuniverse = lrange_sub_mgr.Create(PU_BB_Count * 10); 00180 00181 _complement_region_created = TRUE; 00182 _complement_region = region; 00183 00184 region->Alloc_Subuniverses(); 00185 return region; 00186 } 00187 00189 GRA_REGION* 00190 GRA_REGION_MGR::Create_Prev_Allocated( RID* rid ) 00191 { 00192 GRA_REGION* region = Create(rid); 00193 00194 region->next = _first_prev_alloc_region; 00195 _first_prev_alloc_region = region; 00196 return region; 00197 } 00198 00200 // Get GRA's encapsulation for the region identified by <rid>. Creates it 00201 // if not already. The region is allocated in the GRA_pool. <rid> is the 00202 // RID associated with the blocks in the region. For previously allocated 00203 // regions there will be exactly one of this for all the blocks. For the 00204 // complement, there may be more than one. I don't know that we care. 00205 GRA_REGION* 00206 GRA_REGION_MGR::Get( RID* rid ) 00207 { 00208 if ( rid == NULL || ! RID_has_reg_alloc(rid) ) { 00209 if ( _complement_region_created ) 00210 return _complement_region; 00211 else 00212 return Create_Complement(rid); 00213 } 00214 else { 00215 Is_True(RID_id(rid) <= Last_Region_Id(), ("Region out of bounds")); 00216 // 00217 // only want outermost region contained within this unit (which itself 00218 // may be a region). all inner regions are to be treated as a black 00219 // box. this is primarily to allow splitting to stop at region boundries, 00220 // but we don't recolor regions anyway, so who cares. if we ever want 00221 // to recolor them, though, we'll have to undo this and treat regions as 00222 // we do loops (i.e. set the regs_used bit vectors by walking the trees 00223 // and such ... blech). 00224 // 00225 RID *rid_tmp; 00226 for (rid_tmp = rid; 00227 RID_type(rid_tmp) != RID_TYPE_swp && RID_parent(rid_tmp) != Current_Rid; 00228 rid_tmp = RID_parent(rid_tmp)); 00229 if ( _map[RID_id(rid_tmp)] != NULL ) 00230 return _map[RID_id(rid_tmp)]; 00231 else 00232 return _map[RID_id(rid_tmp)] = Create_Prev_Allocated(rid); 00233 } 00234 } 00235 00236 00238 // second state: stepping the locals 00239 void 00240 GRA_REGION_RC_LRANGE_ITER::Step_Locals(void) 00241 { 00242 INT32 j; 00243 LRANGE_SUBUNIVERSE* l_su = _region->Local_Subuniverse(); 00244 00245 for ( j = _i - 1; j >= 0; --j ) { 00246 LRANGE* current = l_su->Nth_Lrange(j); 00247 if ( current->Rc() == _rc ) { 00248 _i = j; 00249 _current = current; 00250 return; 00251 } 00252 } 00253 _state = done; 00254 } 00255 00257 // first state: stepping the non_locals 00258 void 00259 GRA_REGION_RC_LRANGE_ITER::Step_Non_Locals(void) 00260 { 00261 if ( --_i >= 0 ) { 00262 _current = _region->Subuniverse(_rc)->Nth_Lrange(_i); 00263 } 00264 else if ( _region == gra_region_mgr.Complement_Region() ) { 00265 // Switch states. Set things up as if we had just stepped the nth+1 00266 // local so we can just call Step_Locals. 00267 _i = _region->Local_Subuniverse()->Count(); 00268 _state = in_locals; 00269 Step_Locals(); 00270 } 00271 else _state = done; 00272 } 00273 00275 void 00276 GRA_REGION_RC_LRANGE_ITER::Init(GRA_REGION* region, 00277 ISA_REGISTER_CLASS rc ) 00278 { 00279 LRANGE_SUBUNIVERSE* nl_su = region->Subuniverse(rc); 00280 00281 _region = region; 00282 _rc = rc; 00283 00284 if (nl_su->Count() > 0 ) { 00285 _i = nl_su->Count() - 1; 00286 _current = nl_su->Nth_Lrange(_i); 00287 _state = in_non_locals; 00288 } 00289 else if ( _region == gra_region_mgr.Complement_Region() ) { 00290 // Set things up as if we had just stepped the nth+1 local so we can just 00291 // call Step_Locals. 00292 _i = _region->Local_Subuniverse()->Count(); 00293 _state = in_locals; 00294 Step_Locals(); 00295 } 00296 else _state = done; 00297 }
1.5.6