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
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #define __STDC_LIMIT_MACROS
00063 #include <stdint.h>
00064 #if defined(BUILD_OS_DARWIN)
00065 #include <darwin_elf.h>
00066 #else
00067 #include <elf.h>
00068 #endif
00069 #include <sys/elf_whirl.h>
00070 #include <sys/types.h>
00071 #if defined(__MINGW32__)
00072 #include <WINDOWS.h>
00073 #endif
00074 #include "defs.h"
00075
00076 #define BACK_END // needed by config.h
00077 #include "glob.h"
00078 #include "flags.h"
00079 #include "wn.h"
00080 #include "tracing.h"
00081 #include "ir_reader.h"
00082 #include "const.h"
00083 #include "pu_info.h"
00084 #include "ir_bwrite.h"
00085 #include "cxx_memory.h"
00086
00087 #include "ipl_summary.h"
00088 #include "ipl_summarize.h"
00089 #include "ipl_bread_write.h"
00090 #include "ipl_array_bread_write.h"
00091 #include "optimizer.h"
00092 #include "ipl_driver.h"
00093 #include "config.h"
00094 #include "config_debug.h"
00095 #include "config_opt.h"
00096 #include "config_ipa.h"
00097 #include "ipl_main.h"
00098 #include "ipl_summarize_template.h"
00099 #include "ipl_analyze_template.h"
00100 #include "ipl_cost_template.h"
00101 #include "ipl_outline.h"
00102 #include "wb_ipl.h"
00103 #include "ipa_section_main.h"
00104 #include "ipl_elfsym.h"
00105
00106
00107 BOOL Trace_IPA = FALSE;
00108 BOOL Trace_Perf = FALSE;
00109
00110 BOOL Debug_On = FALSE;
00111 BOOL DoPreopt = FALSE;
00112 BOOL Do_Const = FALSE;
00113 BOOL Do_Par = FALSE;
00114 BOOL Do_Split_Commons = TRUE;
00115 BOOL Do_Split_Commons_Set = FALSE;
00116 BOOL Do_Common_Const = FALSE;
00117 BOOL IPL_Enable_Outline = FALSE;
00118 BOOL IPL_Enable_Unknown_Frequency = FALSE;
00119 #if defined(__linux__) || defined(BUILD_OS_DARWIN)
00120 BOOL IPL_Generate_Elf_Symtab = TRUE;
00121 #else
00122 BOOL IPL_Generate_Elf_Symtab = FALSE;
00123 #endif // __linux__
00124 #ifdef KEY
00125 UINT32 IPL_Ignore_Small_Loops = 0;
00126 #endif
00127
00128
00129
00130
00131 mUINT8 Optlevel = 0;
00132
00133 static INT driver_argc = 0;
00134 static char **driver_argv;
00135
00136 static OPTION_DESC Options_IPL[] = {
00137 { OVK_BOOL, OV_INTERNAL, FALSE, "debug", "",
00138 0, 0, 0, &Debug_On, NULL},
00139 { OVK_BOOL, OV_INTERNAL, FALSE, "const", "",
00140 0, 0, 0, &Do_Const, NULL},
00141 { OVK_BOOL, OV_INTERNAL, FALSE, "par", "",
00142 0, 0, 0, &Do_Par, NULL},
00143 { OVK_BOOL, OV_INTERNAL, FALSE, "outline", "",
00144 0, 0, 0, &IPL_Enable_Outline, NULL},
00145 { OVK_BOOL, OV_INTERNAL, FALSE, "unknown", "",
00146 0, 0, 0, &IPL_Enable_Unknown_Frequency, NULL},
00147 { OVK_BOOL, OV_INTERNAL, FALSE, "elf_symtab", "",
00148 0, 0, 0, &IPL_Generate_Elf_Symtab, NULL},
00149 #ifdef KEY
00150 { OVK_UINT32, OV_INTERNAL, FALSE, "ignore_small_loops", "",
00151 0, 0, UINT32_MAX, &IPL_Ignore_Small_Loops, NULL},
00152 #endif
00153 { OVK_COUNT }
00154 };
00155
00156
00157 OPTION_GROUP IPL_Option_Groups[] = {
00158 { "IPL", ':', '=', Options_IPL },
00159 { NULL }
00160 };
00161
00162
00163 SUMMARY *Summary;
00164 WN_MAP Parent_Map;
00165 WN_MAP Summary_Map;
00166 WN_MAP Stmt_Map;
00167
00168 FILE* STDOUT = stdout;
00169 DYN_ARRAY<char*>* Ipl_Symbol_Names = NULL;
00170 DYN_ARRAY<char*>* Ipl_Function_Names = NULL;
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 static void
00182 Process_Command_Line (INT argc, char **argv)
00183 {
00184 INT i;
00185
00186 for (i = 0; i < argc; i++) {
00187 if (argv[i] != NULL && *(argv[i]) == '-') {
00188
00189 char *arg_str = argv[i];
00190 if (Process_Command_Line_Group (arg_str+1,
00191 IPL_Option_Groups))
00192 {
00193 continue;
00194 }
00195 if (strcmp (arg_str, "-cmds") == 0) {
00196 driver_argc = argc - i - 1;
00197 if (driver_argc > 0)
00198 driver_argv = argv + i + 1;
00199 i = argc;
00200 }
00201 }
00202 }
00203
00204 if (OPT_Reorg_Common_Set)
00205 Do_Split_Commons = OPT_Reorg_Common;
00206
00207 Do_Split_Commons_Set = OPT_Reorg_Common_Set && OPT_Reorg_Common;
00208
00209 Do_Par = IPA_Enable_Array_Summary && Run_preopt;
00210
00211 if (Do_Par)
00212 WOPT_Enable_Generate_DU = TRUE;
00213
00214 Do_Common_Const = IPA_Enable_Common_Const && Run_preopt;
00215
00216 }
00217
00218 void
00219 ipl_main (INT ipl_argc, char **ipl_argv)
00220 {
00221 extern char *Whirl_Revision;
00222
00223 if (strcmp (Whirl_Revision, WHIRL_REVISION) != 0)
00224 FmtAssert (!DEBUG_Ir_Version_Check,
00225 ("WHIRL revision mismatch between be.so (%s) and ipl.so (%s)",
00226 Whirl_Revision, WHIRL_REVISION));
00227
00228
00229 Process_Command_Line (ipl_argc, ipl_argv);
00230 Optlevel = Opt_Level;
00231 }
00232
00233
00234
00235 void
00236 Ipl_Init (void)
00237 {
00238 Set_Error_Phase ( "Ipl Initialization" );
00239
00240 Summary = CXX_NEW (SUMMARY(Malloc_Mem_Pool), Malloc_Mem_Pool);
00241
00242
00243 Init_write_asections (Malloc_Mem_Pool);
00244
00245 }
00246
00247
00248
00249 void
00250 Ipl_Init_From_Ipa (MEM_POOL* pool)
00251 {
00252 Summary = CXX_NEW (SUMMARY(pool), pool);
00253 Init_write_asections (pool);
00254 }
00255
00256
00257
00258
00259
00260 void
00261 Perform_Procedure_Summary_Phase (WN* w, struct DU_MANAGER *du_mgr,
00262 struct ALIAS_MANAGER *alias_mgr,
00263 void *emitter)
00264 {
00265 Trace_IPA = Get_Trace (TP_IPL, TT_IPL_IPA);
00266
00267 if ( Debug_On )
00268 IR_reader_init();
00269
00270 if (IPL_Enable_Outline) {
00271 const WN* wn = Outline_Split_Point (w, IPA_PU_Minimum_Size,
00272 IPA_Small_Callee_Limit / 2);
00273 if (wn) {
00274 fprintf (TFile, "Splitting %s:\n", ST_name (WN_st (w)));
00275 fdump_tree (TFile, const_cast<WN*> (wn));
00276 }
00277 }
00278
00279 if (Trace_IPA) {
00280 fprintf ( TFile, "Summarizing procedure %s \n", ST_name(WN_st(w)) );
00281 }
00282
00283 DoPreopt = Run_preopt;
00284 if (Run_preopt && Cur_PU_Feedback) {
00285 BOOL not_pass = Cur_PU_Feedback->Verify ("IPL");
00286 if (not_pass)
00287 DevWarn ("Feedback verify fails after preopt");
00288 }
00289
00290 WB_IPL_Set_Scalar_Summary(Summary);
00291 WB_IPL_Set_Array_Summary(NULL);
00292 Summary->Set_du_mgr (du_mgr);
00293 Summary->Set_alias_mgr (alias_mgr);
00294 Summary->Set_emitter ((EMITTER *) emitter);
00295 Summary->Summarize (w);
00296 WB_IPL_Set_Array_Summary(NULL);
00297 WB_IPL_Set_Scalar_Summary(NULL);
00298
00299 }
00300
00301 void
00302 Ipl_Fini (void)
00303 {
00304 Summary->Set_global_addr_taken_attrib ();
00305 return;
00306 }
00307
00308
00309 void
00310 Ipl_Extra_Output (Output_File *ir_output)
00311 {
00312 #ifndef KEY
00313 if(IPA_Enable_Reorder)
00314 #endif // !KEY
00315 Summary->Finish_collect_struct_access();
00316 IPA_write_summary(IPA_irb_write_summary, ir_output);
00317
00318 if ( Get_Trace ( TKIND_IR, TP_IPL ) )
00319 IPA_Trace_Summary_File ( TFile, ir_output, TRUE,
00320 Ipl_Symbol_Names, Ipl_Function_Names );
00321
00322 if (driver_argc > 0)
00323 WN_write_flags (driver_argc, driver_argv, ir_output);
00324
00325 #if defined(__linux__) || defined(BUILD_OS_DARWIN)
00326
00327 IPL_Write_Elf_Symtab (ir_output);
00328 #endif // __linux__
00329
00330 }