diff mbox

[GOOGLE] Enhance LIPO support in AutoFDO

Message ID CAO2gOZUnWfCT3AJXLOoVZmFRLeZ-n7+rtfK3Ve3QBFmods8VNA@mail.gmail.com
State New
Headers show

Commit Message

Dehao Chen April 27, 2013, 8:31 p.m. UTC
This patch improves the LIPO support in AutoFDO to make it more robust.

Bootstrapped and passed regression test and benchmark tests.

Ok for google 4_7 branch?

Thanks,
Dehao

http://codereview.appspot.com/8624045
diff mbox

Patch

Index: gcc/opts.h
===================================================================
--- gcc/opts.h (revision 198362)
+++ gcc/opts.h (working copy)
@@ -409,6 +409,6 @@  extern void set_struct_debug_option (struct gcc_op
      const char *value);
 extern bool opt_enum_arg_to_value (size_t opt_index, const char *arg,
    int *value, unsigned int lang_mask);
-extern void write_opts_to_asm (void);
+extern void write_lipo_info_to_asm (void);
 extern void pattern_match_function_attributes (tree);
 #endif
Index: gcc/c-family/c-opts.c
===================================================================
--- gcc/c-family/c-opts.c (revision 198362)
+++ gcc/c-family/c-opts.c (working copy)
@@ -1157,8 +1157,6 @@  c_common_parse_file (void)
   for (;;)
     {
       c_finish_options ();
-      if (flag_record_gcc_switches_in_elf && i == 0)
- write_opts_to_asm ();
       pch_init ();
       set_lipo_c_parsing_context (parse_in, i, verbose);
       push_file_scope ();
Index: gcc/toplev.c
===================================================================
--- gcc/toplev.c (revision 198362)
+++ gcc/toplev.c (working copy)
@@ -1961,6 +1961,8 @@  do_compile (void)
           timevar_stop (TV_PHASE_SETUP);

           compile_file ();
+  if (flag_record_lipo_info_in_elf)
+    write_lipo_info_to_asm ();
         }
       else
         {
Index: gcc/coverage.c
===================================================================
--- gcc/coverage.c (revision 198362)
+++ gcc/coverage.c (working copy)
@@ -376,7 +376,7 @@  has_incompatible_cg_opts (bool *cg_opts1, bool *cg

 /* Returns true if the command-line arguments stored in the given module-infos
    are incompatible.  */
-static bool
+bool
 incompatible_cl_args (struct gcov_module_info* mod_info1,
       struct gcov_module_info* mod_info2)
 {
@@ -2866,7 +2866,7 @@  coverage_init (const char *filename, const char* s
       strcat (main_input_file_name, source_name);
     }

-  if (flag_branch_probabilities)
+  if (flag_branch_probabilities && !flag_auto_profile)
     read_counts_file (da_file_name, 0);

   /* Reads at most one auxiliary GCDA file since we don't support merging */
@@ -3109,16 +3109,32 @@  coverage_has_asm_stmt (void)
 /* Write command line options to the .note section.  */

 void
-write_opts_to_asm (void)
+write_lipo_info_to_asm (void)
 {
   size_t i;
   cpp_dir *quote_paths, *bracket_paths, *pdir;
   struct str_list *pdef, *pinc;
   int num_quote_paths = 0;
   int num_bracket_paths = 0;
+  unsigned lang;

   get_include_chains (&quote_paths, &bracket_paths);

+  /* Write lang, ggc_memory to ASM section.  */
+  switch_to_section (get_section (".gnu.switches.text.lipo_info",
+  SECTION_DEBUG, NULL));
+  if (!strcmp (lang_hooks.name, "GNU C"))
+    lang = GCOV_MODULE_C_LANG;
+  else if (!strcmp (lang_hooks.name, "GNU C++"))
+    lang = GCOV_MODULE_CPP_LANG;
+  else
+    lang = GCOV_MODULE_UNKNOWN_LANG;
+  if (has_asm_statement)
+    lang |= GCOV_MODULE_ASM_STMTS;
+  dw2_asm_output_nstring (in_fnames[0], (size_t)-1, NULL);
+  dw2_asm_output_data_uleb128 (lang, NULL);
+  dw2_asm_output_data_uleb128 (ggc_total_memory, NULL);
+
   /* Write quote_paths to ASM section.  */
   switch_to_section (get_section (".gnu.switches.text.quote_paths",
   SECTION_DEBUG, NULL));
Index: gcc/coverage.h
===================================================================
--- gcc/coverage.h (revision 198362)
+++ gcc/coverage.h (working copy)
@@ -87,6 +87,9 @@  extern tree get_const_string_type (void);
 /* Mark this module as containing asm statements.  */
 extern void coverage_has_asm_stmt (void);

+extern bool incompatible_cl_args (struct gcov_module_info *,
+  struct gcov_module_info *);
+
 /* Defined in tree-profile.c.  */
 extern void tree_init_instrumentation_sampling (void);
 extern void tree_init_dyn_ipa_parameters (void);
Index: gcc/common.opt
===================================================================
--- gcc/common.opt (revision 198362)
+++ gcc/common.opt (working copy)
@@ -1822,8 +1822,8 @@  Record gcc command line switches in the object fil
 ; divide the command line options into several categories. And the
 ; section is not mergable so that linker can save gcc switches for
 ; each module.
-frecord-gcc-switches-in-elf
-Common Report Var(flag_record_gcc_switches_in_elf)
+frecord-lipo-info-in-elf
+Common Report Var(flag_record_lipo_info_in_elf)
 Record the compiler optimizations in a .gnu.switches.text section.

 freg-struct-return
Index: gcc/auto-profile.c
===================================================================
--- gcc/auto-profile.c (revision 198362)
+++ gcc/auto-profile.c (working copy)
@@ -39,6 +39,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "cgraph.h"
 #include "tree-flow.h"
 #include "value-prof.h"
+#include "coverage.h"
 #include "auto-profile.h"

 /* The following routines implements AutoFDO optimization.
@@ -143,7 +144,8 @@  struct afdo_module
   char *name;
   int ident;
   unsigned exported;
-  unsigned has_asm;
+  unsigned lang;
+  unsigned ggc_memory;
   unsigned num_aux_modules;
   unsigned num_quote_paths;
   unsigned num_bracket_paths;
@@ -283,7 +285,8 @@  afdo_stack_hash (const void *stack)
     const char *file = afdo_get_filename (p->file);
     const char *func = afdo_get_bfd_name (p->func);
     h = iterative_hash (file, strlen (file), h);
-    h = iterative_hash (func, strlen (func), h);
+    if (func)
+      h = iterative_hash (func, strlen (func), h);
     h = iterative_hash (&p->line, sizeof (p->line), h);
     if (i == 0)
       h = iterative_hash (&p->discr, sizeof (p->discr), h);
@@ -326,8 +329,11 @@  afdo_stack_eq (const void *p, const void *q)
     {
       const struct gcov_callsite_pos *p1 = s1->stack + i;
       const struct gcov_callsite_pos *p2 = s2->stack + i;
+      const char *func1 = afdo_get_bfd_name (p1->func);
+      const char *func2 = afdo_get_bfd_name (p2->func);
+
       if (strcmp (afdo_get_filename (p1->file), afdo_get_filename (p2->file))
-  || strcmp (afdo_get_bfd_name (p1->func), afdo_get_bfd_name (p2->func))
+  || (func1 != NULL && func2 != NULL && strcmp (func1, func2))
   || p1->line != p2->line || (i== 0 && p1->discr != p2->discr))
  return 0;
     }
@@ -460,6 +466,8 @@  afdo_add_module (struct gcov_module_info **module_
   (*module_info)->ident = module->ident;
   (*module_info)->is_primary = is_primary;
   (*module_info)->flags = is_primary ? module->exported : 1;
+  (*module_info)->lang = module->lang;
+  (*module_info)->ggc_memory = module->ggc_memory;
   (*module_info)->source_filename = module->name;
   (*module_info)->num_quote_paths = module->num_quote_paths;
   (*module_info)->num_bracket_paths = module->num_bracket_paths;
@@ -502,8 +510,37 @@  read_aux_modules (void)
   inform (0, "aux module %s cannot be found.", module.name);
   continue;
  }
-      afdo_add_module (&module_infos[curr_module++], aux_entry, false);
-      add_input_filename (module.name);
+      if ((aux_entry->lang & GCOV_MODULE_LANG_MASK) !=
+  (entry->lang & GCOV_MODULE_LANG_MASK))
+ {
+  inform (0, "Not importing %s: source language"
+  " different from primary module's source language",
+  aux_entry->name);
+  continue;
+ }
+      if ((aux_entry->lang & GCOV_MODULE_ASM_STMTS)
+   && flag_ripa_disallow_asm_modules)
+ {
+  if (flag_opt_info >= OPT_INFO_MIN)
+    inform (0, "Not importing %s: contains "
+    "assembler statements", aux_entry->name);
+  continue;
+ }
+      afdo_add_module (&module_infos[curr_module], aux_entry, false);
+      if (incompatible_cl_args (module_infos[0], module_infos[curr_module]))
+ {
+  if (flag_opt_info >= OPT_INFO_MIN)
+    inform (0, "Not importing %s: command-line"
+    " arguments not compatible with primary module",
+    aux_entry->name);
+  free (module_infos[curr_module]);
+  continue;
+ }
+      else
+ {
+  curr_module ++;
+  add_input_filename (module.name);
+ }
     }
 }

@@ -1238,8 +1275,8 @@  read_profile (void)
       modules[i].ident = i + 1;
       /* exported flag. */
       modules[i].exported = gcov_read_unsigned ();
-      /* has_asm flag.  */
-      modules[i].has_asm = gcov_read_unsigned ();
+      modules[i].lang = gcov_read_unsigned ();
+      modules[i].ggc_memory = gcov_read_unsigned ();
       /* aux_module and 5 options.  */
       modules[i].num_aux_modules = gcov_read_unsigned ();
       modules[i].num_quote_paths = gcov_read_unsigned ();
@@ -1856,6 +1893,13 @@  auto_profile (void)
       pop_cfun ();
     }

+  cgraph_pre_profiling_inlining_done = true;
+  cgraph_process_module_scope_statics ();
+  /* Now perform link to allow cross module inlining.  */
+  cgraph_do_link ();
+  varpool_do_link ();
+  cgraph_unify_type_alias_sets ();
+
   return TODO_rebuild_cgraph_edges;
 }