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
00040
00041
00042
00043
00044
00045 #define __STDC_LIMIT_MACROS
00046 #include <stdint.h>
00047 #if defined(BUILD_OS_DARWIN)
00048 #include <darwin_elf.h>
00049 #else
00050 #include <elf.h>
00051 #endif
00052
00053 #include "defs.h"
00054 #include "errors.h"
00055 #include "mempool.h"
00056 #include "tlog.h"
00057
00058 #include "cgb.h"
00059 #include "cgb_ipa.h"
00060 #include "ipaa.h"
00061 #include "ipa_cg.h"
00062 #include "ipa_cprop.h"
00063 #include "ipa_inline.h"
00064 #include "ipa_option.h"
00065 #include "ipa_pad.h"
00066 #include "ipa_preopt.h"
00067 #include "ipa_section_annot.h"
00068 #include "ipa_section_prop.h"
00069 #include "ipa_nested_pu.h"
00070 #include "ipo_tlog_utils.h"
00071
00072 #include "ipa_chg.h"
00073 #include "ipa_devirtual.h"
00074
00075 #include "ipo_defs.h"
00076
00077 #ifndef KEY
00078 #include "inline_script_parser.h"
00079 #else
00080 extern void (*Preprocess_struct_access_p)(void);
00081 #define Preprocess_struct_access (*Preprocess_struct_access_p)
00082 #endif
00083 #include "ipa_reorder.h"
00084
00085 FILE* STDOUT = stdout;
00086
00087
00088
00089
00090
00091
00092 static void Print_Array_Sections(const char buffer[])
00093 {
00094 CG_BROWSER cgb_print;
00095 CGB_Initialize(&cgb_print, IPA_Call_Graph);
00096 IPA_NODE_ITER cg_iter(cgb_print.Ipa_Cg(), PREORDER);
00097 if (Get_Trace(TP_IPA, IPA_TRACE_SECTION_CORRECTNESS)) {
00098 fprintf(stdout, "%s\n", buffer);
00099 fprintf(TFile, "%s\n", buffer);
00100 }
00101 if (Get_Trace(TP_PTRACE1, TP_PTRACE1_IPALNO))
00102 Generate_Tlog("IPA", "Array_Section", (SRCPOS) 0, "", "", "", buffer);
00103 for (cg_iter.First(); !cg_iter.Is_Empty(); cg_iter.Next()) {
00104 IPA_NODE* ipan = cg_iter.Current();
00105 if (ipan == NULL)
00106 continue;
00107 NODE_INDEX v = cgb_print.Find_Vertex(ipan);
00108 if (v == INVALID_NODE_INDEX)
00109 continue;
00110 if (Get_Trace(TP_IPA, IPA_TRACE_SECTION_CORRECTNESS)) {
00111 fprintf(stdout, "%s\n", ipan->Name());
00112 fprintf(TFile, "%s\n", ipan->Name());
00113 }
00114 cgb_print.Set_Cnode(ipan);
00115 cgb_print.Set_Cvertex(v);
00116 IPA_NODE_SECTION_INFO* ipas = ipan->Section_Annot();
00117 SECTION_FILE_ANNOT* ipaf = IP_FILE_HDR_section_annot(ipan->File_Header());
00118 if (ipas == NULL || ipaf == NULL)
00119 continue;
00120 if (Get_Trace(TP_IPA, IPA_TRACE_SECTION_CORRECTNESS)) {
00121 if (cgb_print.Cnode()->Summary_Proc() != NULL
00122 && cgb_print.Cnode()->Summary_Proc()->Has_incomplete_array_info())
00123 fprintf(stdout, "INCOMPLETE ARRAY INFO\n");
00124 cgb_print.Mod_Ref_Formals(stdout);
00125 cgb_print.Mod_Ref_Commons(stdout);
00126 cgb_print.Mod_Ref_Formals(TFile);
00127 cgb_print.Mod_Ref_Commons(TFile);
00128 }
00129 if (Get_Trace(TP_PTRACE1, TP_PTRACE1_IPALNO)) {
00130 cgb_print.Tlog_Mod_Ref_Formals();
00131 cgb_print.Tlog_Mod_Ref_Commons();
00132 }
00133 }
00134 }
00135
00136 #ifndef KEY
00137
00138
00139
00140
00141 static void Perform_Inline_Script_Analysis(IPA_CALL_GRAPH* cg, MEM_POOL* pool, MEM_POOL* parser_pool)
00142 {
00143 BOOL result = FALSE;
00144 IPA_NODE_ITER cg_iter (cg, LEVELORDER, pool);
00145
00146 #ifdef Enable_ISP_Verify // Additional debug information -- to be removed
00147 int null_caller_count = 0;
00148 int null_callee_count = 0;
00149 #endif
00150
00151
00152 for (cg_iter.First(); !cg_iter.Is_Empty(); cg_iter.Next()) {
00153 IPA_NODE* caller = cg_iter.Current();
00154 if(caller) {
00155 IPA_NODE_CONTEXT context (caller);
00156 cg->Map_Callsites (caller);
00157
00158 IPA_SUCC_ITER edge_iter (cg, caller);
00159 for (edge_iter.First (); !edge_iter.Is_Empty (); edge_iter.Next ()) {
00160 IPA_EDGE *edge = edge_iter.Current_Edge ();
00161 if (edge) {
00162
00163 IPA_NODE* callee = cg->Callee (edge);
00164 WN* call_wn = edge->Whirl_Node();
00165
00166
00167 INT32 callsite_linenum;
00168 USRCPOS callsite_srcpos;
00169 char *caller_filename, *callee_filename;
00170 char *caller_funcname, *callee_funcname;
00171
00172 IP_FILE_HDR& caller_hdr = caller->File_Header ();
00173 IP_FILE_HDR& callee_hdr = callee->File_Header ();
00174
00175 if (call_wn == NULL) {
00176 fprintf (stderr, "Warning: no source line number found for call-edge [%s --> %s]\n",
00177 caller->Name(), callee->Name());
00178 callsite_linenum = 0;
00179 }
00180 else {
00181 USRCPOS_srcpos(callsite_srcpos) = WN_Get_Linenum (call_wn);
00182 callsite_linenum = USRCPOS_linenum(callsite_srcpos);
00183 }
00184
00185 caller_filename = (char *) alloca(strlen(caller_hdr.file_name)+1);
00186 strcpy(caller_filename, caller_hdr.file_name);
00187 callee_filename = (char *) alloca(strlen(callee_hdr.file_name)+1);
00188 strcpy(callee_filename, callee_hdr.file_name);
00189
00190 #ifdef Enable_ISP_Verify // Additional debug information -- to be removed
00191 fprintf (stderr, "Inline script analysis for call pair");
00192 fprintf (stderr, "(Name: %s, Line: %d, File: %s) -> callee (Name: %s, File: %s)\n",
00193 caller->Name(), callsite_linenum, caller_filename,
00194 callee->Name(), callee_filename);
00195 #endif
00196
00197
00198 char *caller_key, *callee_key;
00199 ISP_Fix_Filename(caller_filename);
00200 caller_funcname = (char *) alloca(strlen(DEMANGLE (caller->Name()))+1);
00201 strcpy(caller_funcname, DEMANGLE (caller->Name()));
00202 ISP_Fix_Filename(caller_funcname);
00203
00204 caller_key = (char *) alloca(strlen(caller_filename)+strlen(caller_funcname)+2);
00205 strcpy(caller_key, "");
00206 strcat(caller_key, caller_filename);
00207 strcat(caller_key, caller_funcname);
00208
00209 ISP_Fix_Filename(callee_filename);
00210 callee_funcname = (char *) alloca(strlen(DEMANGLE (callee->Name()))+1);
00211 strcpy(callee_funcname, DEMANGLE (callee->Name()));
00212 ISP_Fix_Filename(callee_funcname);
00213
00214 char callsite_linestr[30];
00215 sprintf(callsite_linestr, "%d", callsite_linenum);
00216
00217 callee_key = (char *) alloca(strlen(callsite_linestr)+strlen(callee_filename)+strlen(callee_funcname)+3);
00218 strcpy(callee_key, "");
00219 strcat(callee_key, callsite_linestr);
00220 strcat(callee_key, callee_filename);
00221 strcat(callee_key, callee_funcname);
00222
00223 result = Check_Inline_Script(INLINE_Script_Name, caller_key, callee_key, parser_pool);
00224
00225
00226 if(result == TRUE) {
00227 edge->Set_Must_Inline_Attrib();
00228 } else {
00229 edge->Set_Noinline_Attrib();
00230 }
00231 }
00232 #ifdef Enable_ISP_Verify // Additional debug information -- to be removed
00233 else null_callee_count++;
00234 #endif
00235 }
00236 }
00237 #ifdef Enable_ISP_Verify // Additional debug information -- to be removed
00238 else null_caller_count++;
00239 #endif
00240 }
00241
00242 #ifdef Enable_ISP_Verify // Additional debug information -- to be removed
00243 fprintf (stderr, "Inline script DEBUG null_caller = %d, null_callee = %d\n", null_caller_count, null_callee_count);
00244 #endif
00245 #ifdef Enable_ISP_Verify
00246 Verify_Inline_Script();
00247 #endif
00248 }
00249 #endif
00250
00251 extern void IPA_struct_opt_legality (void);
00252
00253
00254
00255
00256 void
00257 Perform_Interprocedural_Analysis ()
00258 {
00259 BOOL has_nested_pu = FALSE;
00260 BOOL run_autopar = FALSE;
00261
00262 MEM_POOL_Popper pool (MEM_phase_nz_pool_ptr);
00263
00264 if(IPA_Enable_Reorder)
00265 Init_merge_access();
00266
00267
00268 for (UINT i = 0; i < IP_File_header.size(); ++i) {
00269 IPA_Process_File (IP_File_header[i]);
00270 if (IP_FILE_HDR_has_nested_pu(IP_File_header[i]))
00271 has_nested_pu = TRUE;
00272 if (IP_FILE_HDR_file_header(IP_File_header[i])->Run_AutoPar())
00273 run_autopar = TRUE;
00274 }
00275
00276 if ( Get_Trace ( TP_IPA,IPA_TRACE_TUNING_NEW ) && IPA_Enable_Reorder ) {
00277 fprintf ( TFile,
00278 "\n%s%s\tstruct_access info after merging\n%s%s\n",
00279 DBar, DBar, DBar, DBar );
00280 print_merged_access ();
00281 }
00282
00283 if (run_autopar) {
00284 #ifndef KEY
00285
00286 if (!IPA_Max_Node_Clones_Set) {
00287 IPA_Max_Node_Clones = 5;
00288 }
00289 if (!IPA_Enable_Preopt_Set) {
00290 IPA_Enable_Preopt = TRUE;
00291 }
00292 #endif // !KEY
00293 }
00294 else {
00295
00296 IPA_Enable_Array_Sections = FALSE;
00297 }
00298
00299 if (IPA_Enable_Padding || IPA_Enable_Split_Common) {
00300 Temporary_Error_Phase ephase ("IPA Padding Analysis");
00301 if (Verbose) {
00302 fprintf (stderr, "Common blocks padding/split analysis ...");
00303 fflush (stderr);
00304 }
00305 if (Trace_IPA || Trace_Perf)
00306 fprintf (TFile, "\t<<<Padding/Split analysis begins>>>\n");
00307 Padding_Analysis (IP_File_header.size());
00308 if (Trace_IPA || Trace_Perf)
00309 fprintf (TFile, "\t<<<Padding/Split analysis completed>>>\n");
00310 }
00311
00312
00313 {
00314 Temporary_Error_Phase ephase ("IPA Call Graph Construction");
00315
00316 if ( Get_Trace ( TKIND_ALLOC, TP_IPA ) ) {
00317 fprintf ( TFile,
00318 "\n%s%s\tMemory allocation information before Build_call_graph\n%s%s\n",
00319 DBar, DBar, DBar, DBar );
00320 MEM_Trace ();
00321 }
00322
00323 if (Verbose) {
00324 fprintf (stderr, "Building call graphs ...");
00325 fflush (stderr);
00326 }
00327
00328 if (Trace_IPA || Trace_Perf)
00329 fprintf (TFile, "\t<<<Call Graph Construction begins>>>\n");
00330
00331 Build_Call_Graph ();
00332
00333 if(Get_Trace(TP_IPA, IPA_TRACE_TUNING))
00334 {
00335 FILE *tmp_call_graph = fopen("cg_dump.log", "w");
00336
00337 if(tmp_call_graph != NULL)
00338 {
00339 fprintf(tmp_call_graph, "\t+++++++++++++++++++++++++++++++++++++++\n");
00340
00341 IPA_Call_Graph->Print_vobose(tmp_call_graph);
00342 fprintf(tmp_call_graph, "\t+++++++++++++++++++++++++++++++++++++++\n");
00343 }
00344 fclose(tmp_call_graph);
00345 }
00346
00347 #ifdef KEY
00348 {
00349 IPA_NODE_ITER cg_iter(IPA_Call_Graph, POSTORDER);
00350
00351
00352 for (cg_iter.First(); !cg_iter.Is_Empty(); cg_iter.Next())
00353 {
00354 if (!IPA_Enable_EH_Region_Removal && !IPA_Enable_Pure_Call_Opt)
00355 break;
00356
00357 IPA_NODE * node = cg_iter.Current();
00358 if (!node) continue;
00359
00360 if (node->PU_Can_Throw() ||
00361 node->Summary_Proc()->Has_side_effect())
00362 {
00363 IPA_PRED_ITER preds (node->Node_Index());
00364 for (preds.First(); !preds.Is_Empty(); preds.Next())
00365 {
00366 IPA_EDGE * edge = preds.Current_Edge();
00367 if (edge)
00368 {
00369 IPA_NODE * caller = IPA_Call_Graph->Caller (edge);
00370
00371 PU caller_pu = Pu_Table[ST_pu((caller)->Func_ST())];
00372 if (IPA_Enable_EH_Region_Removal &&
00373 node->PU_Can_Throw() &&
00374 PU_src_lang (caller_pu) & PU_CXX_LANG)
00375 caller->Set_PU_Can_Throw();
00376
00377 if (node->Summary_Proc()->Has_side_effect())
00378 caller->Summary_Proc()->Set_has_side_effect();
00379 }
00380 }
00381 }
00382 }
00383
00384 if (IPA_Enable_Source_PU_Order || Opt_Options_Inconsistent)
00385 for (UINT i = 0; i < IP_File_header.size(); ++i)
00386 {
00387 Mark_PUs_With_File_Id (IP_FILE_HDR_pu_list (IP_File_header[i]), i);
00388 }
00389 }
00390 #endif
00391
00392
00393 if (INLINE_Enable_Script) {
00394 #ifdef KEY
00395 fprintf (stdout, "inline script not implemented\n");
00396 exit (1);
00397 #else
00398 MEM_POOL script_parser_pool;
00399 MEM_POOL_Initialize(&script_parser_pool, "inlining script parser pool", FALSE);
00400 MEM_POOL_Push(&script_parser_pool);
00401
00402 MEM_POOL_Popper inline_script_pool (MEM_local_nz_pool_ptr);
00403 Perform_Inline_Script_Analysis(IPA_Call_Graph, inline_script_pool.Pool(), &script_parser_pool);
00404
00405 MEM_POOL_Pop(&script_parser_pool);
00406 MEM_POOL_Delete(&script_parser_pool);
00407 #endif
00408 }
00409
00410
00411 if (has_nested_pu) {
00412 Build_Nested_Pu_Relations();
00413 if (Verbose) {
00414 fprintf (stderr, "Building Nested PU Relations...");
00415 fflush (stderr);
00416 }
00417 }
00418 }
00419
00420 #ifdef Is_True_On
00421 CGB_IPA_Initialize(IPA_Call_Graph);
00422 #endif
00423
00424 Ipa_tlog( "Must Inline", 0, "Count %d", Total_Must_Inlined);
00425 Ipa_tlog( "Must Not-Inline", 0, "Count %d", Total_Must_Not_Inlined);
00426
00427 if (Trace_IPA || Trace_Perf)
00428 fprintf (TFile, "\t<<<Call Graph Construction completed>>>\n");
00429
00430 #ifdef TODO
00431 if (IPA_Enable_daVinci) {
00432 cg_display = (daVinci *)
00433 CXX_NEW (daVinci (IPA_Call_Graph->Graph (), Malloc_Mem_Pool),
00434 Malloc_Mem_Pool);
00435
00436 cg_display->Translate_Call_Graph ();
00437 }
00438 #endif // TODO
00439
00440 if ( Get_Trace ( TKIND_ALLOC, TP_IPA ) ) {
00441 fprintf ( TFile,
00442 "\n%s%s\tMemory allocation information after "
00443 "Build_call_graph\n%s%s\n",
00444 DBar, DBar, DBar, DBar );
00445 MEM_Trace ();
00446 }
00447
00448
00449
00450
00451 if ((IPA_Enable_SP_Partition && (IPA_Space_Access_Mode == SAVE_SPACE_MODE))
00452 || IPA_Enable_GP_Partition) {
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470 }
00471
00472
00473 Total_Prog_Size = Orig_Prog_Weight;
00474
00475 MEM_POOL_Push (MEM_local_nz_pool_ptr);
00476
00477 if (IPA_Enable_DVE || IPA_Enable_CGI) {
00478 Temporary_Error_Phase ephase ("IPA Global Variable Optimization");
00479 if (Verbose) {
00480 fprintf (stderr, "Global Variable Optimization ...");
00481 fflush (stderr);
00482 }
00483 if (Trace_IPA || Trace_Perf)
00484 fprintf (TFile, "\t<<<Global Variable Optimization begins>>>\n");
00485 #ifdef TODO
00486 if( IPA_Enable_Feedback ) {
00487 setup_IPA_feedback_phase();
00488 fprintf(IPA_Feedback_dve_fd,
00489 "\nDEAD VARIABLES (defined but not used)\n\n");
00490 }
00491 #endif
00492 extern void Optimize_Global_Variables ();
00493 Optimize_Global_Variables ();
00494
00495 if (Trace_IPA || Trace_Perf)
00496 fprintf (TFile,
00497 "\t<<<Global Variable Optimization completed>>>\n");
00498 #ifdef TODO
00499 if( IPA_Enable_Feedback ) {
00500 cleanup_IPA_feedback_phase ();
00501 fflush(IPA_Feedback_dve_fd);
00502 }
00503 #endif
00504 }
00505
00506 if(IPA_Enable_Reorder && !merged_access->empty())
00507 IPA_reorder_legality_process();
00508
00509 #ifdef KEY
00510 if (IPA_Enable_Struct_Opt)
00511 IPA_struct_opt_legality();
00512 #endif
00513
00514
00515
00516
00517
00518 if (IPA_Enable_DFE) {
00519 Temporary_Error_Phase ephase ("IPA Dead Functions Elimination");
00520 if (Verbose) {
00521 fprintf (stderr, "Dead functions elimination ...");
00522 fflush (stderr);
00523 }
00524 #ifdef TODO
00525 if( IPA_Enable_Feedback ) {
00526
00527
00528
00529
00530
00531
00532 setup_IPA_feedback_phase();
00533 fprintf(IPA_Feedback_dfe_fd,
00534 "\nDEAD FUNCTIONS (but not due to inlining)\n\n");
00535 }
00536 #endif
00537 if (Trace_IPA || Trace_Perf)
00538 fprintf (TFile, "\t<<<Dead Functions Elimination begins>>>\n");
00539 Total_Dead_Function_Weight = Eliminate_Dead_Func ();
00540 Total_Prog_Size = Orig_Prog_Weight - Total_Dead_Function_Weight;
00541 if (Trace_IPA || Trace_Perf)
00542 fprintf (TFile, "\t<<<Dead Functions Elimination completed>>>\n");
00543 #ifdef TODO
00544 if( IPA_Enable_Feedback ) {
00545 cleanup_IPA_feedback_phase ();
00546 fflush(IPA_Feedback_dfe_fd);
00547 }
00548 #endif
00549 }
00550
00551 if (IPA_Enable_Devirtualization) {
00552 Temporary_Error_Phase ephase ("IPA Devirtualization");
00553 IPA_Class_Hierarchy = Build_Class_Hierarchy();
00554 IPA_devirtualization();
00555 }
00556
00557 if ( IPA_Enable_Simple_Alias ) {
00558 Temporary_Error_Phase ephase ("Interprocedural Alias Analysis");
00559 if (Verbose) {
00560 fprintf (stderr, "Alias analysis ...");
00561 fflush (stderr);
00562 }
00563
00564 IPAA ipaa(NULL);
00565 ipaa.Do_Simple_IPAA ( *IPA_Call_Graph );
00566
00567 if ( Get_Trace ( TKIND_ALLOC, TP_IPA ) ) {
00568 fprintf ( TFile,
00569 "\n%s%s\tMemory allocation information after IPAA\n%s%s\n",
00570 DBar, DBar, DBar, DBar );
00571 MEM_Trace ();
00572 }
00573 }
00574 else {
00575
00576
00577 IPA_Enable_Cprop = FALSE;
00578 IPA_Enable_Common_Const = FALSE;
00579 IPA_Max_Node_Clones = 0;
00580 }
00581
00582
00583
00584
00585 if (IPA_Enable_Array_Sections &&
00586 IPA_Max_Node_Clones > 0 &&
00587 IPA_Max_Clone_Bloat > 0) {
00588
00589 Temporary_Error_Phase ephase ("IPA Cloning Analysis");
00590 if (Verbose) {
00591 fprintf (stderr, "Cloning Analysis ...");
00592 fflush (stderr);
00593 }
00594 if (Trace_IPA || Trace_Perf) {
00595 fprintf (TFile, "\t<<<Analysis of formals for cloning begins>>>\n");
00596 }
00597
00598 IPA_FORMALS_IN_ARRAY_SECTION_DF clone_df(IPA_Call_Graph,
00599 BACKWARD,
00600 MEM_local_nz_pool_ptr);
00601 clone_df.Init();
00602 clone_df.Solve();
00603
00604 if (Get_Trace(TP_IPA, IPA_TRACE_CPROP_CLONING)) {
00605 clone_df.Print(TFile);
00606 }
00607 if (Trace_IPA || Trace_Perf) {
00608 fprintf (TFile, "\t<<<Analysis of formals for cloning ends>>>\n");
00609 }
00610 }
00611
00612
00613
00614 if (IPA_Enable_Cprop) {
00615 Temporary_Error_Phase ephase ("IPA Constant Propagation");
00616
00617 if ( Get_Trace ( TKIND_ALLOC, TP_IPA ) ) {
00618 fprintf ( TFile,
00619 "\n%s%s\tMemory allocation information before IP constant propagation\n%s%s\n",
00620 DBar, DBar, DBar, DBar );
00621 MEM_Trace ();
00622 }
00623
00624 if (Verbose) {
00625 fprintf (stderr, "Constant propagation ...");
00626 fflush (stderr);
00627 }
00628 if (Trace_IPA || Trace_Perf)
00629 fprintf (TFile, "\t<<<Constant Propagation begins>>>\n");
00630
00631 MEM_POOL_Initialize (&Ipa_cprop_pool, "cprop pool", 0);
00632
00633
00634 IPA_Max_Total_Clones =
00635 (GRAPH_vcnt(IPA_Call_Graph->Graph()) * IPA_Max_Clone_Bloat) / 100;
00636
00637 if (IPA_Enable_Common_Const) {
00638 static BOOL global_cprop_pool_inited = FALSE;
00639 if (!global_cprop_pool_inited) {
00640 MEM_POOL_Initialize(&Global_mem_pool, "global_cprop_mem_pool", 0);
00641 MEM_POOL_Push (&Global_mem_pool);
00642 global_cprop_pool_inited = TRUE;
00643 }
00644 MEM_POOL_Initialize(&local_cprop_pool, "local_cprop_mem_pool", 0);
00645 MEM_POOL_Push(&local_cprop_pool);
00646 }
00647
00648 IPA_CPROP_DF_FLOW df (FORWARD, MEM_local_nz_pool_ptr);
00649
00650 df.Init();
00651 df.Solve();
00652
00653
00654
00655 IPA_NODE_ITER cg_iter(IPA_Call_Graph, POSTORDER);
00656 for (cg_iter.First(); !cg_iter.Is_Empty(); cg_iter.Next()) {
00657 IPA_NODE* node = cg_iter.Current();
00658 if (node && node->Is_Quasi_Clone()) {
00659 IPA_Call_Graph->Quasi_To_Real_Clone(node);
00660 }
00661 }
00662 if (Get_Trace(TP_IPA, IPA_TRACE_CPROP_CLONING)) {
00663 IPA_Call_Graph->Print(TFile);
00664 }
00665
00666 #if 0
00667
00668 for (cg_iter.First(); !cg_iter.Is_Empty(); cg_iter.Next()) {
00669 IPA_NODE* node = (IPA_NODE*) cg_iter.Current();
00670 if (node && node->Is_Quasi_Clone()) {
00671 IPA_Call_Graph->Remove_Quasi_Clone(node);
00672 }
00673 }
00674 #endif
00675
00676 if (IPA_Enable_Common_Const) {
00677 MEM_POOL_Pop(&local_cprop_pool);
00678 MEM_POOL_Delete(&local_cprop_pool);
00679 }
00680
00681
00682 if (Trace_IPA || Trace_Perf) {
00683 df.Print(TFile);
00684 fprintf(TFile, "Constant Count = %d \n", IPA_Constant_Count);
00685 fprintf (TFile,"\t<<<Constant Propagation ends>>>\n");
00686 }
00687 Ipa_tlog( "Cprop", 0, "Count %d", IPA_Constant_Count);
00688
00689 #ifdef TODO
00690
00691 if( IPA_Enable_Feedback ) {
00692 fprintf(IPA_Feedback_con_fd,"\nCONSTANTS FOUND\n\n");
00693 df.Print(IPA_Feedback_con_fd);
00694 fflush(IPA_Feedback_con_fd);
00695 }
00696 #endif // TODO
00697
00698 if (WN_mem_pool_ptr == &Ipa_cprop_pool)
00699 WN_mem_pool_ptr = NULL;
00700 MEM_POOL_Delete (&Ipa_cprop_pool);
00701
00702 if ( Get_Trace ( TKIND_ALLOC, TP_IPA ) ) {
00703 fprintf ( TFile,
00704 "\n%s%s\tMemory allocation information after IP constant propagation\n%s%s\n",
00705 DBar, DBar, DBar, DBar );
00706 MEM_Trace ();
00707 }
00708 }
00709
00710 #ifdef KEY
00711 if (IPA_Enable_Preopt)
00712 Preprocess_struct_access();
00713 #endif // KEY
00714
00715
00716 if (IPA_Enable_Preopt_Set && IPA_Enable_Preopt) {
00717 IPA_NODE_ITER cg_iter(IPA_Call_Graph, POSTORDER);
00718 for (cg_iter.First(); !cg_iter.Is_Empty(); cg_iter.Next()) {
00719 if (IPA_NODE* node = cg_iter.Current()) {
00720 IPA_Preoptimize(node);
00721 }
00722 }
00723 }
00724
00725 MEM_POOL_Pop (MEM_local_nz_pool_ptr);
00726
00727
00728 if (IPA_Enable_Array_Sections) {
00729
00730 Temporary_Error_Phase ephase ("IPA Array Section Analysis");
00731 if ( Get_Trace ( TKIND_ALLOC, TP_IPA ) ) {
00732 fprintf ( TFile,
00733 "\n%s%s\tMemory allocation information before IP array section propagation \n%s%s\n", DBar, DBar, DBar, DBar );
00734 MEM_Trace ();
00735 }
00736 if (Verbose) {
00737 fprintf (stderr, "Array Section analysis ...");
00738 fflush (stderr);
00739 }
00740 if (Trace_IPA || Trace_Perf) {
00741 fprintf (TFile, "\t<<<Array section propagation begins>>>\n");
00742 }
00743
00744 MEM_POOL_Push (MEM_local_nz_pool_ptr);
00745
00746 IPA_ARRAY_DF_FLOW array_df (IPA_Call_Graph,
00747 BACKWARD,
00748 MEM_local_nz_pool_ptr);
00749
00750 array_df.Init();
00751 Print_Array_Sections("BEFORE PROPAGATION:");
00752
00753 array_df.Solve();
00754 Print_Array_Sections("AFTER PROPAGATION:");
00755
00756 if (Trace_IPA || Trace_Perf) {
00757 fprintf (TFile,"\t<<<Array section propagation ends>>>\n");
00758 }
00759
00760 MEM_POOL_Pop (MEM_local_nz_pool_ptr);
00761
00762 if ( Get_Trace ( TKIND_ALLOC, TP_IPA ) ) {
00763 fprintf ( TFile,
00764 "\n%s%s\tMemory allocation information after IP array section propagation \n%s%s\n",
00765 DBar, DBar, DBar, DBar );
00766 MEM_Trace ();
00767 }
00768 }
00769
00770 if (IPA_Enable_Preopt) {
00771 IPA_Preopt_Finalize();
00772 }
00773
00774
00775 if (IPA_Enable_Inline || IPA_Enable_DCE) {
00776
00777 MEM_POOL_Popper inline_pool (MEM_local_nz_pool_ptr);
00778
00779 if (Verbose) {
00780 fprintf (stderr, "Inlining analysis ...");
00781 fflush (stderr);
00782 }
00783
00784 Temporary_Error_Phase ephase ("IPA Inlining Analysis");
00785 if (Trace_IPA || Trace_Perf)
00786 fprintf (TFile, "\t<<<Inlining analysis begins>>>\n");
00787 #ifdef TODO
00788 if( IPA_Enable_Feedback ) {
00789 setup_IPA_feedback_phase();
00790 fprintf(IPA_Feedback_prg_fd,"\nINLINING FAILURE INFO\n\n");
00791 }
00792 #endif
00793 Perform_Inline_Analysis (IPA_Call_Graph, inline_pool.Pool());
00794
00795 if (Trace_IPA || Trace_Perf) {
00796 fprintf (TFile, "\n\tTotal code expansion = %d%%, total prog WHIRL size = 0x%x \n",
00797 Orig_Prog_Weight == 0 ? 0 : (Total_Prog_Size - (INT) Orig_Prog_Weight) * 100 / (INT) Orig_Prog_Weight,
00798 Total_Prog_Size);
00799 fprintf (TFile, "\t<<<Inlining analysis completed>>>\n");
00800 }
00801 #ifdef TODO
00802 if( IPA_Enable_Feedback ) {
00803 cleanup_IPA_feedback_phase ();
00804 fflush(IPA_Feedback_prg_fd);
00805 }
00806 #endif // TODO
00807
00808 Ipa_tlog( "Inline", 0, "Count %d", Total_Inlined);
00809 Ipa_tlog( "Not-Inline", 0, "Count %d", Total_Not_Inlined);
00810 }
00811
00812
00813 #ifdef Is_True_On
00814 CGB_IPA_Terminate();
00815 #endif
00816
00817 }