This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[GOOGLE] Enhance LIPO support in AutoFDO
- From: Dehao Chen <dehao at google dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: David Li <davidxl at google dot com>
- Date: Sat, 27 Apr 2013 13:31:19 -0700
- Subject: [GOOGLE] Enhance LIPO support in AutoFDO
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
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 ("e_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;
}