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
00036
00037
00038
00039
00041
00042
00043
00044
00045
00046
00048
00049
00050
00051
00052
00053
00054
00055 #ifdef USE_PCH
00056 #include "cg_pch.h"
00057 #endif // USE_PCH
00058 #pragma hdrstop
00059
00060 #include "defs.h"
00061 #include "errors.h"
00062 #include "cgir.h"
00063 #include "gra_live.h"
00064 #include "annotations.h"
00065 #include "gra_grant.h"
00066
00067 #include "gra_cflow.h"
00068 #ifdef TARG_IA64
00069 #include "ipfec_options.h"
00070 #include "region_bb_util.h"
00071 #include "cg.h"
00072 #endif
00073
00074 #include "freq.h"
00075
00076 BOOL GRA_split_entry_exit_blocks = TRUE;
00077
00078
00079
00080
00081 static BB_LIST* entry_bbs;
00082 static BB_LIST* exit_bbs;
00083
00085 inline BOOL
00086 OP_Is_Copy_To_Save_TN(const OP* op)
00088
00089
00090
00092 {
00093 INT i;
00094
00095 for ( i = OP_results(op) - 1; i >= 0; --i ) {
00096 TN* tn = OP_result(op,i);
00097 if ( TN_is_save_reg(tn)) return TRUE;
00098 }
00099
00100 return FALSE;
00101 }
00102
00104 inline BOOL
00105 OP_Is_Copy_From_Save_TN( const OP* op )
00107
00108
00109
00111 {
00112 INT i;
00113
00114
00115
00116
00117
00118 for ( i = OP_results(op) - 1; i >= 0; --i ) {
00119 if ( TN_is_dedicated(OP_result(op,i)) ) break;
00120 }
00121 if ( i < 0 ) return FALSE;
00122
00123 for ( i = OP_opnds(op) - 1; i >= 0; --i ) {
00124 TN* tn = OP_opnd(op,i);
00125 if ( TN_Is_Allocatable(tn) && TN_is_save_reg(tn))
00126 return TRUE;
00127 }
00128
00129 return FALSE;
00130 }
00131
00133 static void
00134 Split_Entry( BB* bb )
00136
00137
00138
00139
00140
00141
00143 {
00144 OP* op;
00145 OP* prev_op = NULL;
00146 BB* prev_bb = BB_prev(bb);
00147 BB* new_entry = Create_Dummy_BB(bb);
00148
00149 Insert_BB(new_entry,prev_bb);
00150 BB_Transfer_Entryinfo(bb,new_entry);
00151 BB_freq(new_entry) = BB_freq(bb);
00152
00153 op = BB_last_op(bb);
00154 if (op) {
00155 do {
00156 prev_op = OP_prev(op);
00157 if (OP_Is_Copy_To_Save_TN(op))
00158 BB_Move_Op_To_Start(new_entry, bb, op);
00159 op = prev_op;
00160 } while (op != NULL && op != BB_entry_sp_adj_op(new_entry));
00161 }
00162
00163 for (op = BB_entry_sp_adj_op (new_entry); op != NULL; op = prev_op) {
00164 prev_op = OP_prev(op);
00165 BB_Move_Op_To_Start (new_entry, bb, op);
00166 }
00167
00168 GRA_LIVE_Compute_Local_Info(bb);
00169 GRA_LIVE_Compute_Local_Info(new_entry);
00170 GRA_LIVE_Region_Start();
00171 GRA_LIVE_Region_Entry(new_entry);
00172 GRA_LIVE_Region_Exit(bb);
00173 GRA_LIVE_Region_Compute_Global_Live_Info();
00174
00175 entry_bbs = BB_LIST_Push(new_entry,entry_bbs,GRA_pool);
00176 }
00177
00179 static void
00180 Join_Entry( BB* bb )
00182
00183
00184
00185
00186
00187
00189 {
00190 BB* new_entry = BB_next(bb);
00191
00192 BB_Transfer_Entryinfo(bb,new_entry);
00193 GRA_GRANT_Transfer(bb,new_entry);
00194 BB_Prepend_All(new_entry,bb);
00195 Remove_BB(bb);
00196 Unlink_Pred_Succ(bb,new_entry);
00197 Reset_BB_scheduled(new_entry);
00198 GRA_LIVE_Merge_Blocks(new_entry,bb,new_entry);
00199 }
00200
00202 static void
00203 Split_Exit( BB* bb )
00205
00206
00207
00208
00209
00210
00212 {
00213 OP* op;
00214 OP* next_op = NULL;
00215 BB* new_exit= Gen_And_Insert_BB_After(bb);
00216
00217 BB_Transfer_Exitinfo(bb,new_exit);
00218 BB_freq(new_exit) = BB_freq(bb);
00219
00220 op = BB_first_op(bb);
00221 do {
00222 next_op = OP_next(op);
00223 if (OP_Is_Copy_From_Save_TN(op))
00224 BB_Move_Op_To_End(new_exit, bb, op);
00225 op = next_op;
00226 } while (op != NULL && op != BB_exit_sp_adj_op(new_exit));
00227
00228 for (op = BB_exit_sp_adj_op (new_exit); op != NULL; op = next_op) {
00229 next_op = OP_next(op);
00230 BB_Move_Op_To_End (new_exit, bb, op);
00231 }
00232
00233
00234 Target_Simple_Fall_Through_BB(bb,new_exit);
00235
00236 GRA_LIVE_Compute_Local_Info(bb);
00237 GRA_LIVE_Compute_Local_Info(new_exit);
00238 GRA_LIVE_Region_Start();
00239 GRA_LIVE_Region_Entry(bb);
00240 GRA_LIVE_Region_Exit(new_exit);
00241 GRA_LIVE_Region_Compute_Global_Live_Info();
00242
00243 exit_bbs = BB_LIST_Push(new_exit,exit_bbs,GRA_pool);
00244 }
00245
00247 static void
00248 Join_Exit( BB* bb )
00250
00251
00252
00253
00254
00256 {
00257 BB* new_exit = BB_prev(bb);
00258
00259 BB_Transfer_Exitinfo(bb,new_exit);
00260 GRA_GRANT_Transfer(bb,new_exit);
00261 BB_Append_All(new_exit,bb);
00262 Remove_BB(bb);
00263 Unlink_Pred_Succ(new_exit,bb);
00264 Reset_BB_scheduled(new_exit);
00265 GRA_LIVE_Merge_Blocks(new_exit,new_exit,bb);
00266 }
00267
00269 void
00270 GRA_Split_Entry_And_Exit_BBs(BOOL is_region)
00272
00273
00275 {
00276 BB* bb;
00277 BB* next_bb = NULL;
00278 BB_LIST *elist;
00279
00280 #ifdef KEY
00281 GRA_pu_has_handler = FALSE;
00282 Is_True(GRA_split_entry_exit_blocks,
00283 ("GRA will not work correctly under -GRA:split_entry_exit_blocks=off"));
00284 #else
00285 if ( ! GRA_split_entry_exit_blocks ) return;
00286 #endif
00287
00288 entry_bbs = NULL;
00289 exit_bbs = NULL;
00290
00291 for ( bb = REGION_First_BB; bb != NULL; bb = next_bb ) {
00292 next_bb = BB_next(bb);
00293 #ifdef KEY
00294 if (BB_handler(bb))
00295 GRA_pu_has_handler = TRUE;
00296 #endif
00297 if ( BB_entry(bb) ) {
00298 DevAssert(is_region == FALSE,
00299 ("Procedure/Function entry block in region.\n"));
00300 Split_Entry(bb);
00301 }
00302 }
00303
00304
00305
00306
00307
00308
00309
00310 if ( is_region == FALSE ) {
00311 for ( elist = Exit_BB_Head; elist; elist = BB_LIST_rest(elist) ) {
00312 Split_Exit(BB_LIST_first(elist));
00313 }
00314 }
00315 }
00316
00318 void
00319 GRA_Join_Entry_And_Exit_BBs(void)
00321
00323 {
00324 BB_LIST *bb_list;
00325
00326 if ( ! GRA_split_entry_exit_blocks ) return;
00327
00328 for ( bb_list = entry_bbs;
00329 bb_list != NULL;
00330 bb_list = BB_LIST_rest(bb_list)
00331 ) {
00332 BB* entry_bb = BB_LIST_first(bb_list);
00333
00334 Join_Entry(entry_bb);
00335 }
00336
00337 for ( bb_list = exit_bbs;
00338 bb_list != NULL;
00339 bb_list = BB_LIST_rest(bb_list)
00340 ) {
00341 BB* exit_bb = BB_LIST_first(bb_list);
00342
00343 Join_Exit(exit_bb);
00344 }
00345 }
00346
00348 void
00349 GRA_Add_Call_Spill_Block(BB* bb, BB* succ)
00351
00353 {
00354 #ifdef TARG_IA64
00355 BB *new_succ = NULL;
00356 if(IPFEC_Enable_Region_Formation && RGN_Formed) {
00357 new_succ = RGN_Gen_And_Insert_BB_After(bb);
00358 BB_freq(new_succ) = BB_freq(bb);
00359 RGN_Unlink_Pred_Succ(bb,succ);
00360 RGN_Link_Pred_Succ_With_Prob(bb,new_succ,1.0);
00361 RGN_Link_Pred_Succ_With_Prob(new_succ, succ, 1.0);
00362 } else {
00363 new_succ = Gen_And_Insert_BB_After(bb);
00364 BB_freq(new_succ) = BB_freq(bb);
00365 Change_Succ(bb, succ, new_succ);
00366 Link_Pred_Succ_with_Prob(new_succ, succ, 1.0);
00367 }
00368 #else
00369 BB *new_succ = Gen_And_Insert_BB_After(bb);
00370
00371 #if !defined(TARG_SL)
00372 BB_freq(new_succ) = BB_freq(bb);
00373 #endif
00374
00375 Change_Succ(bb, succ, new_succ);
00376 Link_Pred_Succ_with_Prob(new_succ, succ, 1.0);
00377 #endif // TARG_IA64
00378
00379 #if defined (TARG_SL)
00380 if(FREQ_Frequencies_Computed() || BB_freq_fb_based(bb))
00381 BB_freq(succ) += BB_freq(new_succ);
00382 #endif
00383
00384 GRA_LIVE_Compute_Local_Info(bb);
00385 GRA_LIVE_Compute_Local_Info(new_succ);
00386 GRA_LIVE_Region_Start();
00387 GRA_LIVE_Region_Entry(bb);
00388 GRA_LIVE_Region_Exit(new_succ);
00389 GRA_LIVE_Region_Compute_Global_Live_Info();
00390 }