00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00037
00038
00039
00040
00041
00042
00044
00045
00046
00047
00048
00049
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.cxx $ $Revision: 1.2 $";
00058 #endif
00059
00060 #include "defs.h"
00061 #include "mempool.h"
00062 #include "timing.h"
00063 #include "tracing.h"
00064 #include "cgir.h"
00065 #include "cg.h"
00066 #include "gtn_universe.h"
00067 #include "dominate.h"
00068 #include "cg_flags.h"
00069 #include "gra_bb.h"
00070 #include "gra.h"
00071 #include "gra_region.h"
00072 #include "gra_create.h"
00073 #include "gra_color.h"
00074 #include "gra_spill.h"
00075 #include "gra_grant.h"
00076 #include "gra_cflow.h"
00077 #include "gra_trace.h"
00078 #ifdef TARG_SL2 //para_region_mgr
00079 #include "gra_para_region.h"
00080 #endif
00081
00082
00083 static MEM_POOL GRA_pool_struct;
00084 MEM_POOL* const GRA_pool = &GRA_pool_struct;
00085
00086
00087 INT GRA_pu_num = 0;
00088 float GRA_call_split_freq;
00089 float GRA_spill_count_factor;
00090
00091 #ifdef TARG_IA64
00092 BOOL gra_self_recursive = FALSE;
00093 extern char *Cur_PU_Name;
00094 #endif
00095
00096 static BOOL gra_spill_around_save_tn_copies;
00097
00098
00100 void
00101 GRA_Initialize(void)
00103
00104
00105
00107 {
00108 gra_spill_around_save_tn_copies = TRUE;
00109 }
00110
00112 BOOL
00113 GRA_Spill_Around_Save_TN_Copies(void)
00115
00116
00117
00119 {
00120 return gra_spill_around_save_tn_copies;
00121 }
00122
00124 static void
00125 Initialize_Memory(void)
00127
00128
00129
00131 {
00132 static BOOL did_init = FALSE;
00133
00134 if ( ! did_init ) {
00135 MEM_POOL_Initialize(GRA_pool,"GRA pool",FALSE);
00136 did_init = TRUE;
00137 }
00138 MEM_POOL_Push(GRA_pool);
00139 }
00140
00142 static void
00143 Finalize_Memory(void)
00145
00146
00147
00149 {
00150 if (GRA_loop_splitting) {
00151 Free_Dominators_Memory();
00152 }
00153 MEM_POOL_Pop(GRA_pool);
00154 }
00155
00156
00158 REGISTER_SET
00159 GRA_Local_Register_Grant( BB* bb, ISA_REGISTER_CLASS rc )
00161
00163 {
00164 return GRA_GRANT_Get_Local_Registers(bb,rc);
00165 }
00166
00168 void
00169 GRA_Finalize_Grants(void)
00171
00173 {
00174 GRA_GRANT_Finalize();
00175 }
00176
00178 static void
00179 Clear_Spill_BB_Flags(void)
00181
00182
00183
00185 {
00186 BB *bb;
00187
00188 for (bb = REGION_First_BB; bb; bb = BB_next(bb)) {
00189 Reset_BB_gra_spill(bb);
00190 }
00191 }
00192
00194 static void
00195 Initialize_Flags()
00197
00198
00199
00201 {
00202 gra_spill_around_save_tn_copies = FALSE;
00203 GRA_call_split_freq = atof(GRA_call_split_freq_string);
00204 GRA_spill_count_factor = atof(GRA_spill_count_factor_string);
00205 }
00206
00207 #ifdef TARG_IA64
00208 void
00209 GRA_Fat_Point_Estimate(void) {
00210
00211 Initialize_Memory();
00212 lrange_sub_mgr.Initialize();
00213 lrange_mgr.Initialize();
00214 gbb_mgr.Initialize();
00215 gra_region_mgr.Initialize();
00216
00217 GRA_Pre_Create();
00218
00219 lrange_sub_mgr.Finalize();
00220 lrange_mgr.Finalize();
00221 gbb_mgr.Finalize();
00222 gra_region_mgr.Finalize();
00223
00224 Finalize_Memory();
00225
00226
00227 }
00228
00229
00230
00231
00232
00233
00234
00235 BOOL
00236 Check_Self_Recursive(void) {
00237 BB *bb = NULL;
00238 OP *op = NULL;
00239 INT32 max_live_in = 0;
00240 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
00241 GTN_SET *live_in = BB_live_out(bb);
00242 INT32 size = BS_Size(live_in);
00243 if (size > max_live_in) max_live_in = size;
00244 }
00245
00246 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
00247 FOR_ALL_BB_OPs (bb, op) {
00248 if (OP_call(op)) {
00249 for (INT k = 0; k < OP_opnds(op);k++) {
00250 TN *tn = OP_opnd(op,k);
00251 if (TN_is_symbol(tn)) {
00252 ST *var = TN_var(tn);
00253 if (ST_class(var) != CLASS_CONST) {
00254 char *called_func = ST_name(var);
00255 if (strcmp(called_func,Cur_PU_Name) == 0) {
00256 if ((!gra_self_recursive) && (max_live_in > 100)) {
00257 gra_self_recursive = TRUE;
00258 DevWarn("This FUNCTION IS FAT AND SELF_RECURSIVE ONE!The Max_Live_In is %d\n",max_live_in);
00259 return gra_self_recursive;
00260 }
00261 }
00262 }
00263 }
00264 }
00265 }
00266 }
00267 }
00268
00269 return FALSE;
00270 }
00271 INIT_USE_ONLY_GTN* GTN_USE_ONLY;
00272
00273 void Init_GTN_LIST()
00274 {
00275 GTN_USE_ONLY = NULL;
00276 }
00277 INIT_USE_ONLY_GTN* Create_Use_Only_GTN(MEM_POOL *pool)
00278 {
00279 INIT_USE_ONLY_GTN *gtn_use_only =TYPE_MEM_POOL_ALLOC(INIT_USE_ONLY_GTN,pool);
00280 gtn_use_only ->TN_Number=0;
00281 gtn_use_only ->Used_Time=0;
00282 gtn_use_only->Used_In_BB=0;
00283 gtn_use_only ->next = NULL;
00284 return gtn_use_only;
00285 }
00286
00287 void Free_GTN (MEM_POOL *pool,INIT_USE_ONLY_GTN *delete_tn)
00288 {
00289 MEM_POOL_FREE(pool,delete_tn);
00290 }
00291 BOOL Search_Used_Only_Once_GTN (TN *find_tn,BB* def_bb) {
00292
00293 INIT_USE_ONLY_GTN *head = GTN_USE_ONLY;
00294 if (head==NULL)
00295 return FALSE;
00296 else
00297 while (head !=NULL){
00298 if ((head->TN_Number== TN_number(find_tn))&&(head->Used_Time == 1)) {
00299 if (head->Used_In_BB == BB_id(def_bb))
00300 return TRUE;
00301 }
00302 head = head->next;
00303 }
00304 return FALSE;
00305 }
00306 INIT_USE_ONLY_GTN* Search_GTN_In_List (TN *find_tn)
00307 {
00308 INIT_USE_ONLY_GTN *head = GTN_USE_ONLY;
00309 if (head==NULL)
00310 return NULL;
00311 else
00312 while (head !=NULL){
00313 if (head->TN_Number== TN_number(find_tn)) {
00314 return head;
00315 }
00316 head = head->next;
00317 }
00318 return NULL;
00319 }
00320 void Build_GTN_In_List (TN *tn,BB* bb)
00321 {
00322 INIT_USE_ONLY_GTN *head = GTN_USE_ONLY;
00323 if (!TN_is_global_reg(tn)) return;
00324 if (head == NULL) {
00325 INIT_USE_ONLY_GTN *head = Create_Use_Only_GTN(GRA_pool);
00326 head->TN_Number = TN_number(tn);
00327 head->Used_In_BB=BB_id(bb);
00328 head->Used_Time ++;
00329 GTN_USE_ONLY=head;
00330 return ;
00331 }else {
00332 INIT_USE_ONLY_GTN* find_tn=Search_GTN_In_List(tn);
00333 if(find_tn ==NULL) {
00334 INIT_USE_ONLY_GTN *insert_tn = Create_Use_Only_GTN(GRA_pool);
00335 insert_tn->TN_Number = TN_number(tn);
00336 insert_tn->Used_Time ++;
00337 insert_tn->Used_In_BB=BB_id(bb);
00338 find_tn = GTN_USE_ONLY;
00339 while (find_tn->next !=NULL) {
00340 find_tn= find_tn->next;
00341 }
00342 find_tn->next = insert_tn;
00343 }else {
00344 Is_True (find_tn->TN_Number==TN_number(tn), ("Tn has been changed !"));
00345 find_tn->Used_Time ++;
00346 if (find_tn->Used_Time==1) {
00347 find_tn->Used_In_BB=BB_id(bb);
00348 }else {
00349 find_tn->Used_In_BB=0;
00350 }
00351 }
00352 return;
00353 }
00354 }
00355 void Print_GTN()
00356 {
00357 INIT_USE_ONLY_GTN *head = GTN_USE_ONLY;
00358 fprintf(stdout,"**************Used only once GTN ********\n" );
00359 while (head!=NULL){
00360 if (head->Used_Time == 1)
00361 fprintf(stdout,"GTN :%d \n",head->TN_Number );
00362 head= head->next;
00363 }
00364 fprintf(stdout,"**************End GTN ********\n" );
00365 }
00366
00367 #endif // TARG_IA64
00368
00370 void
00371 GRA_Allocate_Global_Registers( BOOL is_region )
00373
00375 {
00376
00377 Set_Error_Phase ("Global Register Allocation");
00378 Start_Timer (T_GRA_CU);
00379
00380 Initialize_Flags();
00381 Initialize_Memory();
00382 lrange_sub_mgr.Initialize();
00383 lrange_mgr.Initialize();
00384 gbb_mgr.Initialize();
00385 gra_region_mgr.Initialize();
00386 #ifdef TARG_SL2 //para_region_mgr
00387 gra_para_region_mgr.Initialize();
00388 #endif
00389 GRA_Spill_Initialize();
00390 GRA_Trace_Initialize();
00391 #ifdef TARG_IA64
00392 Init_GTN_LIST();
00393 #endif
00394
00395 GRA_Split_Entry_And_Exit_BBs(is_region);
00396
00397 GRA_Create();
00398 GRA_Color();
00399
00400
00401 if (Get_Trace(TKIND_IR, TP_GRA, REGION_First_BB))
00402 Trace_IR(TP_GRA, "GRA0", NULL);
00403
00404 GRA_Spill();
00405 GRA_Delete();
00406
00407 GRA_GRANT_Unused_Caller_Saved();
00408
00409
00410 #if defined (TARG_SL) //minor_reg_alloc
00411 gra_para_region_mgr.Set_Region_LRA_Budget();
00412 #endif
00413
00414 lrange_sub_mgr.Finalize();
00415 lrange_mgr.Finalize();
00416 gbb_mgr.Finalize();
00417 gra_region_mgr.Finalize();
00418
00419 GRA_Join_Entry_And_Exit_BBs();
00420
00421 #ifdef TARG_IA64
00422 Gen_UNAT_Spills_Entry_And_Exit_BB();
00423 GRA_Optimize_Restore();
00424 #endif
00425
00426 Clear_Spill_BB_Flags();
00427
00428 Finalize_Memory();
00429
00430
00431 if (Get_Trace(TKIND_IR, TP_GRA, REGION_First_BB))
00432 Trace_IR(TP_GRA, "GRA", NULL);
00433
00434 GRA_pu_num++;
00435
00436 Stop_Timer ( T_GRA_CU );
00437 }