diff options
author | raksit <raksit@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-04-25 09:18:10 +0000 |
---|---|---|
committer | raksit <raksit@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-04-25 09:18:10 +0000 |
commit | e19b94bb4bb709ff7a04ec9656f2761bbf8924fe (patch) | |
tree | 316099f8fd8a0f7048e037179ea6e0235cee24f5 | |
parent | afa21ffa4e3713f33b4a3f76e9b3bc9862af9929 (diff) |
Fix some overflows during edge count scaling.
Suppress verbose LIPO messages - now controlled by a new option -fripa-verbose.
Record if a module has asm, and provide a for way for such modules to not be
imported/exported.
Record -include/-imacro in the gcda files, and have these applied to
the auxiliary modules during profile-use (like we do for -D/-U/etc...
options currently).
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/lw-ipo@158700 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/Makefile.in | 2 | ||||
-rw-r--r-- | gcc/c-opts.c | 6 | ||||
-rw-r--r-- | gcc/cfg.c | 20 | ||||
-rw-r--r-- | gcc/common.opt | 8 | ||||
-rw-r--r-- | gcc/coverage.c | 162 | ||||
-rw-r--r-- | gcc/coverage.h | 3 | ||||
-rw-r--r-- | gcc/cp/cp-objcp-common.c | 8 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 19 | ||||
-rw-r--r-- | gcc/dyn-ipa.c | 6 | ||||
-rw-r--r-- | gcc/gcov-io.c | 6 | ||||
-rw-r--r-- | gcc/gcov-io.h | 13 | ||||
-rw-r--r-- | gcc/opts.h | 1 | ||||
-rw-r--r-- | gcc/profile.c | 1 | ||||
-rw-r--r-- | gcc/stmt.c | 2 | ||||
-rw-r--r-- | gcc/tree-inline.c | 15 | ||||
-rw-r--r-- | gcc/value-prof.c | 60 |
16 files changed, 225 insertions, 107 deletions
diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 1a9f23dfee1..fd316328027 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2775,7 +2775,7 @@ stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(FLAGS_H) $(FUNCTION_H) insn-config.h hard-reg-set.h $(EXPR_H) \ libfuncs.h $(EXCEPT_H) $(RECOG_H) $(TOPLEV_H) output.h $(GGC_H) $(TM_P_H) \ langhooks.h $(PREDICT_H) $(OPTABS_H) $(TARGET_H) $(GIMPLE_H) $(MACHMODE_H) \ - $(REGS_H) alloc-pool.h $(PRETTY_PRINT_H) + $(REGS_H) alloc-pool.h $(PRETTY_PRINT_H) $(COVERAGE_H) except.o : except.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(FLAGS_H) $(EXCEPT_H) $(FUNCTION_H) $(EXPR_H) libfuncs.h \ langhooks.h insn-config.h hard-reg-set.h $(BASIC_BLOCK_H) output.h \ diff --git a/gcc/c-opts.c b/gcc/c-opts.c index dc61c3ee07e..e8441c36e1f 100644 --- a/gcc/c-opts.c +++ b/gcc/c-opts.c @@ -1555,6 +1555,7 @@ finish_options (void) if (opt->code == OPT_imacros && cpp_push_include (parse_in, opt->arg)) { + coverage_note_include (opt->arg); /* Disable push_command_line_include callback for now. */ include_cursor = deferred_count + 1; cpp_scan_nooutput (parse_in); @@ -1578,7 +1579,10 @@ push_command_line_include (void) if (!cpp_opts->preprocessed && opt->code == OPT_include && cpp_push_include (parse_in, opt->arg)) - return; + { + coverage_note_include (opt->arg); + return; + } } if (include_cursor == deferred_count) diff --git a/gcc/cfg.c b/gcc/cfg.c index 834bb5cc2bd..f064211cf6f 100644 --- a/gcc/cfg.c +++ b/gcc/cfg.c @@ -1042,7 +1042,7 @@ scale_bbs_frequencies_int (basic_block *bbs, int nbbs, int num, int den) if (num > 1000000) return; - num = RDIV (1000 * num, den); + num = RDIV (1000.0 * num, den); den = 1000; } if (num > 100 * den) @@ -1055,9 +1055,9 @@ scale_bbs_frequencies_int (basic_block *bbs, int nbbs, int num, int den) /* Make sure the frequencies do not grow over BB_FREQ_MAX. */ if (bbs[i]->frequency > BB_FREQ_MAX) bbs[i]->frequency = BB_FREQ_MAX; - bbs[i]->count = RDIV (bbs[i]->count * num, den); + bbs[i]->count = RDIV ((double)bbs[i]->count * num, den); FOR_EACH_EDGE (e, ei, bbs[i]->succs) - e->count = RDIV (e->count * num, den); + e->count = RDIV ((double)e->count * num, den); } } @@ -1074,7 +1074,7 @@ scale_bbs_frequencies_gcov_type (basic_block *bbs, int nbbs, gcov_type num, { int i; edge e; - gcov_type fraction = RDIV (num * 65536, den); + gcov_type fraction = RDIV (num * 65536.0, den); gcc_assert (fraction >= 0); @@ -1084,14 +1084,14 @@ scale_bbs_frequencies_gcov_type (basic_block *bbs, int nbbs, gcov_type num, edge_iterator ei; bbs[i]->frequency = RDIV (bbs[i]->frequency * num, den); if (bbs[i]->count <= MAX_SAFE_MULTIPLIER) - bbs[i]->count = RDIV (bbs[i]->count * num, den); + bbs[i]->count = RDIV ((double)bbs[i]->count * num, den); else - bbs[i]->count = RDIV (bbs[i]->count * fraction, 65536); + bbs[i]->count = RDIV ((double)bbs[i]->count * fraction, 65536); FOR_EACH_EDGE (e, ei, bbs[i]->succs) if (bbs[i]->count <= MAX_SAFE_MULTIPLIER) - e->count = RDIV (e->count * num, den); + e->count = RDIV ((double)e->count * num, den); else - e->count = RDIV (e->count * fraction, 65536); + e->count = RDIV ((double)e->count * fraction, 65536); } else for (i = 0; i < nbbs; i++) @@ -1101,9 +1101,9 @@ scale_bbs_frequencies_gcov_type (basic_block *bbs, int nbbs, gcov_type num, bbs[i]->frequency = RDIV (bbs[i]->frequency * num, den); else bbs[i]->frequency = RDIV (bbs[i]->frequency * fraction, 65536); - bbs[i]->count = RDIV (bbs[i]->count * fraction, 65536); + bbs[i]->count = RDIV ((double)bbs[i]->count * fraction, 65536); FOR_EACH_EDGE (e, ei, bbs[i]->succs) - e->count = RDIV (e->count * fraction, 65536); + e->count = RDIV ((double)e->count * fraction, 65536); } } diff --git a/gcc/common.opt b/gcc/common.opt index da594b809fd..a5e24f29f18 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -490,10 +490,18 @@ fdump-unnumbered-links Common Report Var(flag_dump_unnumbered_links) VarExists Suppress output of previous and next insn numbers in debugging dumps +fripa-disallow-asm-modules +Common Report Var(flag_ripa_disallow_asm_modules) +Don't import an auxiliary module if it contains asm statements + fripa-disallow-opt-mismatch Common Report Var(flag_ripa_disallow_opt_mismatch) Don't import an auxiliary module if the command line options mismatch with the primary module +fripa-verbose +Common Report Var(flag_ripa_verbose) +Enable verbose informational messages for LIPO compilation + fearly-inlining Common Report Var(flag_early_inlining) Init(1) Optimization Perform early inlining diff --git a/gcc/coverage.c b/gcc/coverage.c index 83aac87612e..4fa49486fd8 100644 --- a/gcc/coverage.c +++ b/gcc/coverage.c @@ -64,13 +64,11 @@ struct function_list unsigned n_ctrs[GCOV_COUNTERS];/* number of counters. */ }; -/* Linked list of -D/-U strings for a - source module. */ - -struct cpp_def_list +/* Linked list of -D/-U/-imacro/-include strings for a source module. */ +struct str_list { - char *cpp_def; - struct cpp_def_list *next; + char *str; + struct str_list *next; }; /* Counts information for a function. */ @@ -133,9 +131,16 @@ static bool rebuilding_counts_hash = false; struct gcov_module_info **module_infos = NULL; /* List of -D/-U options. */ -static struct cpp_def_list *cpp_defines_head = NULL, *cpp_defines_tail = NULL; +static struct str_list *cpp_defines_head = NULL, *cpp_defines_tail = NULL; static unsigned num_cpp_defines = 0; +/* List of -imcaro/-include options. */ +static struct str_list *cpp_includes_head = NULL, *cpp_includes_tail = NULL; +static unsigned num_cpp_includes = 0; + +/* True if the current module has any asm statements. */ +static bool has_asm_statement; + /* Forward declarations. */ static hashval_t htab_counts_entry_hash (const void *); static int htab_counts_entry_eq (const void *, const void *); @@ -220,9 +225,11 @@ incompatible_cl_args (struct gcov_module_info* mod_info1, bool warning_mismatch = false; bool non_warning_mismatch = false; unsigned int start_index1 = mod_info1->num_quote_paths + - mod_info1->num_bracket_paths + mod_info1->num_cpp_defines; + mod_info1->num_bracket_paths + mod_info1->num_cpp_defines + + mod_info1->num_cpp_includes; unsigned int start_index2 = mod_info2->num_quote_paths + - mod_info2->num_bracket_paths + mod_info2->num_cpp_defines; + mod_info2->num_bracket_paths + mod_info2->num_cpp_defines + + mod_info2->num_cpp_includes; /* First, separate the warning and non-warning options. */ for (i = 0; i < mod_info1->num_cl_args; i++) @@ -445,6 +452,7 @@ read_counts_file (const char *da_file_name, unsigned module_id) sizeof (void *) * (mod_info->num_quote_paths + mod_info->num_bracket_paths + mod_info->num_cpp_defines + + mod_info->num_cpp_includes + mod_info->num_cl_args)); /* The first MODULE_INFO record must be for the primary module. */ if (module_infos_read == 0) @@ -466,7 +474,8 @@ read_counts_file (const char *da_file_name, unsigned module_id) if (pointer_set_insert (modset, (void *)(size_t)mod_info->ident)) inform (input_location, "Not importing %s: already imported", mod_info->source_filename); - else if (module_infos[0]->lang != mod_info->lang) + else if ((module_infos[0]->lang & GCOV_MODULE_LANG_MASK) != + (mod_info->lang & GCOV_MODULE_LANG_MASK)) inform (input_location, "Not importing %s: source language" " different from primary module's source language", mod_info->source_filename); @@ -480,6 +489,10 @@ read_counts_file (const char *da_file_name, unsigned module_id) else if ((fd = open (aux_da_filename, O_RDONLY)) < 0) inform (input_location, "Not importing %s: couldn't open %s", mod_info->source_filename, aux_da_filename); + else if ((mod_info->lang & GCOV_MODULE_ASM_STMTS) + && flag_ripa_disallow_asm_modules) + inform (input_location, "Not importing %s: contains assembler" + " statements", mod_info->source_filename); else { close (fd); @@ -495,15 +508,15 @@ read_counts_file (const char *da_file_name, unsigned module_id) } } - /* Debugging */ - { - inform (input_location, - "MODULE Id=%d, Is_Primary=%s," - " Is_Exported=%s, Name=%s (%s)", - mod_info->ident, mod_info->is_primary?"yes":"no", - mod_info->is_exported?"yes":"no", mod_info->source_filename, - mod_info->da_filename); - } + if (flag_ripa_verbose) + { + inform (input_location, + "MODULE Id=%d, Is_Primary=%s," + " Is_Exported=%s, Name=%s (%s)", + mod_info->ident, mod_info->is_primary?"yes":"no", + mod_info->is_exported?"yes":"no", mod_info->source_filename, + mod_info->da_filename); + } } gcov_sync (offset, length); if ((is_error = gcov_is_error ())) @@ -603,8 +616,9 @@ get_coverage_counts (unsigned counter, unsigned expected, if (!entry) { - warning (0, "no coverage for function %qE found", - DECL_ASSEMBLER_NAME (current_function_decl)); + if (!flag_dyn_ipa) + warning (0, "no coverage for function %qE found", + DECL_ASSEMBLER_NAME (current_function_decl)); return NULL; } @@ -1182,32 +1196,32 @@ build_inc_path_array_value (tree string_type, tree inc_path_value, return inc_path_value; } -/* Returns an array (tree) of macro def strings. STRING_TYPE is - the string type, CPP_DEF_VALUE is the initial value of the - macro array, and HEAD gives the list of raw strings. */ +/* Returns an array (tree) of strings. STR_TYPE is the string type, + STR_ARRAY_VALUE is the initial value of the string array, and HEAD gives + the list of raw strings. */ static tree -build_cpp_def_array_value (tree string_type, tree cpp_def_value, - struct cpp_def_list *head) +build_str_array_value (tree str_type, tree str_array_value, + struct str_list *head) { - const char *def_raw_string; - int def_string_length; + const char *raw_str; + int str_length; while (head) { - tree def_string; - def_raw_string = head->cpp_def; - def_string_length = strlen (def_raw_string); - def_string = build_string (def_string_length + 1, def_raw_string); - TREE_TYPE (def_string) = + tree str; + raw_str = head->str; + str_length = strlen (raw_str); + str = build_string (str_length + 1, raw_str); + TREE_TYPE (str) = build_array_type (char_type_node, build_index_type (build_int_cst (NULL_TREE, - def_string_length))); - cpp_def_value = tree_cons (NULL_TREE, - build1 (ADDR_EXPR, string_type, def_string), - cpp_def_value); + str_length))); + str_array_value = tree_cons (NULL_TREE, + build1 (ADDR_EXPR, str_type, str), + str_array_value); head = head->next; } - return cpp_def_value; + return str_array_value; } /* Returns an array (tree) of command-line argument strings. STRING_TYPE is @@ -1295,6 +1309,8 @@ build_gcov_module_info_value (void) lang = GCOV_MODULE_CPP_LANG; else lang = GCOV_MODULE_UNKNOWN_LANG; + if (has_asm_statement) + lang |= GCOV_MODULE_ASM_STMTS; value = tree_cons (field, build_int_cstu (get_gcov_unsigned_t (), lang), value); @@ -1358,6 +1374,14 @@ build_gcov_module_info_value (void) value = tree_cons (field, build_int_cstu (get_gcov_unsigned_t (), num_cpp_defines), value); + /* Num -imacro/-include options. */ + field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, + get_gcov_unsigned_t ()); + TREE_CHAIN (field) = fields; + fields = field; + value = tree_cons (field, build_int_cstu (get_gcov_unsigned_t (), + num_cpp_includes), value); + /* Num command-line args. */ field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ()); @@ -1371,14 +1395,17 @@ build_gcov_module_info_value (void) num_quote_paths + num_bracket_paths + num_cpp_defines + + num_cpp_includes + num_lipo_cl_args)); string_array_type = build_array_type (string_type, index_type); string_array = build_inc_path_array_value (string_type, string_array, quote_paths, num_quote_paths); string_array = build_inc_path_array_value (string_type, string_array, bracket_paths, num_bracket_paths); - string_array = build_cpp_def_array_value (string_type, string_array, - cpp_defines_head); + string_array = build_str_array_value (string_type, string_array, + cpp_defines_head); + string_array = build_str_array_value (string_type, string_array, + cpp_includes_head); string_array = build_cl_args_array_value (string_type, string_array); string_array = build_constructor_from_list (string_array_type, nreverse (string_array)); @@ -1742,6 +1769,12 @@ set_lipo_c_parsing_context (struct cpp_reader *parse_in, int i, bool verbose) cpp_define (parse_in, mod_info->string_array[j] + 1); else cpp_undef (parse_in, mod_info->string_array[j] + 1); + + /* Setup -imacro/-include. */ + for (i = 0, j = mod_info->num_quote_paths + mod_info->num_bracket_paths + + mod_info->num_cpp_defines; i < mod_info->num_cpp_includes; + i++, j++) + cpp_push_include (parse_in, mod_info->string_array[j]); } } @@ -1755,6 +1788,7 @@ coverage_init (const char *filename, const char* source_name) int src_name_prefix_len = 0; int len = strlen (filename); + has_asm_statement = false; da_file_name = get_da_file_name (filename); da_base_file_name = XNEWVEC (char, strlen (filename) + 1); strcpy (da_base_file_name, filename); @@ -1815,6 +1849,23 @@ coverage_finish (void) } } +/* Add S to the end of the string-list, the head and tail of which are + pointed-to by HEAD and TAIL, respectively. */ + +static void +str_list_append (struct str_list **head, struct str_list **tail, const char *s) +{ + struct str_list *e = XNEW (struct str_list); + e->str = XNEWVEC (char, strlen (s) + 1); + strcpy (e->str, s); + e->next = NULL; + if (*tail) + (*tail)->next = e; + else + *head = e; + *tail = e; +} + /* Copies the macro def or undef CPP_DEF and saves the copy in a list. IS_DEF is a flag indicating if CPP_DEF represents a -D or -U. */ @@ -1822,17 +1873,28 @@ coverage_finish (void) void coverage_note_define (const char *cpp_def, bool is_def) { - struct cpp_def_list *d = XNEW (struct cpp_def_list); - d->cpp_def = XNEWVEC (char, strlen (cpp_def) + 2); - d->cpp_def[0] = is_def ? 'D' : 'U'; - strcpy (d->cpp_def + 1, cpp_def); - d->next = NULL; + char *s = XNEWVEC (char, strlen (cpp_def) + 2); + s[0] = is_def ? 'D' : 'U'; + strcpy (s + 1, cpp_def); + str_list_append (&cpp_defines_head, &cpp_defines_tail, s); num_cpp_defines++; - if (cpp_defines_tail) - cpp_defines_tail->next = d; - else - cpp_defines_head = d; - cpp_defines_tail = d; +} + +/* Copies the -imacro/-include FILENAME and saves the copy in a list. */ + +void +coverage_note_include (const char *filename) +{ + str_list_append (&cpp_includes_head, &cpp_includes_tail, filename); + num_cpp_includes++; +} + +/* Mark this module as containing asm statements. */ + +void +coverage_has_asm_stmt (void) +{ + has_asm_statement = flag_ripa_disallow_asm_modules; } #include "gt-coverage.h" diff --git a/gcc/coverage.h b/gcc/coverage.h index ad5c4868108..eaa500ab0a8 100644 --- a/gcc/coverage.h +++ b/gcc/coverage.h @@ -66,4 +66,7 @@ extern bool coverage_function_present (unsigned fn_ident); extern tree get_gcov_type (void); extern tree get_gcov_unsigned_t (void); +/* Mark this module as containing asm statements. */ +extern void coverage_has_asm_stmt (void); + #endif diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c index d800b9f1f27..3eafd9a185e 100644 --- a/gcc/cp/cp-objcp-common.c +++ b/gcc/cp/cp-objcp-common.c @@ -631,16 +631,14 @@ cp_save_built_in_decl_post_parsing (void) for (i = 0; VEC_iterate (saved_builtin, saved_builtins, i, bi); ++i) { - if (TREE_CODE (bi->decl) != FUNCTION_DECL - || DECL_ARTIFICIAL (bi->decl) - || DECL_BUILT_IN (bi->decl)) - continue; + if (!TREE_STATIC (bi->decl) || DECL_ARTIFICIAL (bi->decl)) + continue; /* Remember the defining module. */ cgraph_link_node (cgraph_node (bi->decl)); if (!bi->decl_fini_copy) bi->decl_fini_copy = lipo_save_decl (bi->decl); else - gcc_assert (!DECL_BUILT_IN (bi->decl_fini_copy)); + gcc_assert (TREE_STATIC (bi->decl_fini_copy)); } } diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index c0ebdf9617f..6055680930b 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -367,8 +367,9 @@ Objective-C and Objective-C++ Dialects}. -freciprocal-math -fregmove -frename-registers -freorder-blocks @gol -freorder-blocks-and-partition -freorder-functions @gol -frerun-cse-after-loop -freschedule-modulo-scheduled-loops @gol --fripa -fripa-disallow-opt-mismatch -frounding-math -fsched2-use-superblocks @gol --fsched2-use-traces -fsched-pressure @gol +-fripa -fripa-disallow-asm-modules @gol +-fripa-disallow-opt-mismatch -fripa-verbose -frounding-math @gol +-fsched2-use-superblocks -fsched2-use-traces -fsched-pressure @gol -fsched-spec-load -fsched-spec-load-dangerous @gol -fsched-stalled-insns-dep[=@var{n}] -fsched-stalled-insns[=@var{n}] @gol -fsched-group-heuristic -fsched-critical-path-heuristic @gol @@ -7481,12 +7482,26 @@ instrumentation code that enables dynamic call-graph analysis. During the @option{-fprofile-use} phase, this flag enables cross-module optimizations such as inlining. +@item -fripa-disallow-asm-modules +@opindex fripa-disallow-asm-modules +During profile-gen, if this flag is enabled, and the module has asm statements, +arrange so that a bit recording this information will be set in the profile +feedback data file. +During profile-use, if this flag is enabled, and the same bit in auxiliary +module's profile feedback data is set, don't import this auxiliary module. +If this is the primary module, don't export it. + @item -fripa-disallow-opt-mismatch @opindex fripa-disallow-opt-mismatch Don't import an auxiliary module, if the GCC command line options used for this auxiliary module during the profile-generate stage were different from those used for the primary module. Note that any mismatches in warning-related options are ignored for this comparison. + +@item -fripa-verbose +@opindex fripa-verbose +Enable printing of verbose information about dynamic inter-procedural optimizations. +This is used in conjunction with the @option{-fripa}. @end table The following options control compiler behavior regarding floating diff --git a/gcc/dyn-ipa.c b/gcc/dyn-ipa.c index db0a63daf28..99ceb43174c 100644 --- a/gcc/dyn-ipa.c +++ b/gcc/dyn-ipa.c @@ -1055,7 +1055,8 @@ gcov_write_module_info (const struct gcov_info *mod_info, len += 2; /* each name string is led by a length. */ num_strings = module_info->num_quote_paths + module_info->num_bracket_paths + - module_info->num_cpp_defines + module_info->num_cl_args; + module_info->num_cpp_defines + module_info->num_cpp_includes + + module_info->num_cl_args; for (i = 0; i < num_strings; i++) { gcov_unsigned_t string_len @@ -1065,7 +1066,7 @@ gcov_write_module_info (const struct gcov_info *mod_info, len += 1; /* Each string is lead by a length. */ } - len += 8; /* 8 more fields */ + len += 9; /* 9 more fields */ gcov_write_tag_length (GCOV_TAG_MODULE_INFO, len); gcov_write_unsigned (module_info->ident); @@ -1075,6 +1076,7 @@ gcov_write_module_info (const struct gcov_info *mod_info, gcov_write_unsigned (module_info->num_quote_paths); gcov_write_unsigned (module_info->num_bracket_paths); gcov_write_unsigned (module_info->num_cpp_defines); + gcov_write_unsigned (module_info->num_cpp_includes); gcov_write_unsigned (module_info->num_cl_args); /* Now write the filenames */ diff --git a/gcc/gcov-io.c b/gcc/gcov-io.c index d356ffbe6d6..4c83a9f91e1 100644 --- a/gcc/gcov-io.c +++ b/gcc/gcov-io.c @@ -512,8 +512,9 @@ gcov_read_module_info (struct gcov_module_info *mod_info, mod_info->num_quote_paths = gcov_read_unsigned (); mod_info->num_bracket_paths = gcov_read_unsigned (); mod_info->num_cpp_defines = gcov_read_unsigned (); + mod_info->num_cpp_includes = gcov_read_unsigned (); mod_info->num_cl_args = gcov_read_unsigned (); - len -= 8; + len -= 9; filename_len = gcov_read_unsigned (); mod_info->da_filename = (char *) xmalloc (filename_len * @@ -530,7 +531,8 @@ gcov_read_module_info (struct gcov_module_info *mod_info, len -= (src_filename_len + 1); num_strings = mod_info->num_quote_paths + mod_info->num_bracket_paths + - mod_info->num_cpp_defines + mod_info->num_cl_args; + mod_info->num_cpp_defines + mod_info->num_cpp_includes + + mod_info->num_cl_args; for (j = 0; j < num_strings; j++) { gcov_unsigned_t string_len = gcov_read_unsigned (); diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h index dc85f345fe3..a9932d5037c 100644 --- a/gcc/gcov-io.h +++ b/gcc/gcov-io.h @@ -453,6 +453,9 @@ struct gcov_summary #define GCOV_MODULE_CPP_LANG 2 #define GCOV_MODULE_FORT_LANG 3 +#define GCOV_MODULE_ASM_STMTS (1 << 16) +#define GCOV_MODULE_LANG_MASK 0xffff + /* Source module info. The data structure is used in both runtime and profile-use phase. Make sure to allocate enough space for the variable length member. */ @@ -464,19 +467,25 @@ struct gcov_module_info (2) means IS_PRIMARY in persistent file or memory copy used in profile-use. */ gcov_unsigned_t is_exported; - gcov_unsigned_t lang; + gcov_unsigned_t lang; /* lower 16 bits encode the language, and the upper + 16 bits enocde other attributes, such as whether + any assembler is present in the source, etc. */ char *da_filename; char *source_filename; gcov_unsigned_t num_quote_paths; gcov_unsigned_t num_bracket_paths; gcov_unsigned_t num_cpp_defines; + gcov_unsigned_t num_cpp_includes; gcov_unsigned_t num_cl_args; char *string_array[1]; }; extern struct gcov_module_info **module_infos; extern unsigned primary_module_id; -#define PRIMARY_MODULE_EXPORTED module_infos[0]->is_exported +#define PRIMARY_MODULE_EXPORTED \ + (module_infos[0]->is_exported \ + && !((module_infos[0]->lang & GCOV_MODULE_ASM_STMTS) \ + && flag_ripa_disallow_asm_modules)) /* Structures embedded in coveraged program. The structures generated by write_profile must match these. */ diff --git a/gcc/opts.h b/gcc/opts.h index 0788342db6a..ff59ec70751 100644 --- a/gcc/opts.h +++ b/gcc/opts.h @@ -121,4 +121,5 @@ extern void add_input_filename (const char *filename); extern void add_module_info (unsigned mod_id, bool is_primary, int index); extern void set_lipo_c_parsing_context (struct cpp_reader *parse_in, int i, bool verbose); extern void coverage_note_define (const char *cpp_def, bool is_def); +extern void coverage_note_include (const char *filename); #endif diff --git a/gcc/profile.c b/gcc/profile.c index 3f9739a8087..fe82d02735b 100644 --- a/gcc/profile.c +++ b/gcc/profile.c @@ -283,6 +283,7 @@ is_edge_inconsistent (VEC(edge,gc) *edges) { if (e->count < 0 && (!(e->flags & EDGE_FAKE) + || e->src == ENTRY_BLOCK_PTR || !block_ends_with_call_p (e->src))) { if (dump_file) diff --git a/gcc/stmt.c b/gcc/stmt.c index 14f13812b36..01b6ce821cc 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -52,6 +52,7 @@ along with GCC; see the file COPYING3. If not see #include "regs.h" #include "alloc-pool.h" #include "pretty-print.h" +#include "coverage.h" /* Functions and data structures for expanding case statements. */ @@ -1087,6 +1088,7 @@ expand_asm_operands (tree string, tree outputs, tree inputs, emit_move_insn (real_output_rtx[i], output_rtx[i]); crtl->has_asm_statement = 1; + coverage_has_asm_stmt (); free_temp_slots (); } diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index f9cf872cab1..bfb56cb9adc 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1474,7 +1474,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, basic_block_info automatically. */ copy_basic_block = create_basic_block (NULL, (void *) 0, (basic_block) bb->prev_bb->aux); - copy_basic_block->count = bb->count * count_scale / REG_BR_PROB_BASE; + copy_basic_block->count = (double)bb->count * count_scale / REG_BR_PROB_BASE; /* We are going to rebuild frequencies from scratch. These values have just small importance to drive canonicalize_loop_headers. */ @@ -1839,7 +1839,8 @@ copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb) && old_edge->dest->aux != EXIT_BLOCK_PTR) flags |= EDGE_FALLTHRU; new_edge = make_edge (new_bb, (basic_block) old_edge->dest->aux, flags); - new_edge->count = old_edge->count * count_scale / REG_BR_PROB_BASE; + new_edge->count + = old_edge->count * (double)count_scale / REG_BR_PROB_BASE; new_edge->probability = old_edge->probability; } @@ -1979,7 +1980,7 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count) gcov_type count_scale; if (ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count) - count_scale = (REG_BR_PROB_BASE * count + count_scale = (REG_BR_PROB_BASE * (double)count / ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count); else count_scale = REG_BR_PROB_BASE; @@ -2017,12 +2018,12 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count) profile_status_for_function (cfun) = profile_status_for_function (src_cfun); ENTRY_BLOCK_PTR->count = - (ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count * count_scale / - REG_BR_PROB_BASE); + (ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count * (double)count_scale / + REG_BR_PROB_BASE); ENTRY_BLOCK_PTR->frequency = ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->frequency; EXIT_BLOCK_PTR->count = - (EXIT_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count * count_scale / + (EXIT_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count * (double)count_scale / REG_BR_PROB_BASE); EXIT_BLOCK_PTR->frequency = EXIT_BLOCK_PTR_FOR_FUNCTION (src_cfun)->frequency; @@ -2055,7 +2056,7 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale, int last; if (ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count) - count_scale = (REG_BR_PROB_BASE * count + count_scale = (REG_BR_PROB_BASE * (double)count / ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count); else count_scale = REG_BR_PROB_BASE; diff --git a/gcc/value-prof.c b/gcc/value-prof.c index 5c42fa18683..d65e89c4dd1 100644 --- a/gcc/value-prof.c +++ b/gcc/value-prof.c @@ -1498,17 +1498,20 @@ gimple_ic_transform_mult_targ (gimple stmt, histogram_value histogram) if (direct_call1 == NULL || !check_ic_target (gimple_call_fn (stmt), direct_call1)) { - if (!direct_call1) - inform (locus, "Can not find indirect call target decl " - "(%d:%d)[cnt:%u] in current module", - EXTRACT_MODULE_ID_FROM_GLOBAL_ID (val1), - EXTRACT_FUNC_ID_FROM_GLOBAL_ID (val1), (unsigned) count1); - else - inform (locus, - "Can not find promote indirect call target decl -- type mismatch " - "(%d:%d)[cnt:%u] in current module", - EXTRACT_MODULE_ID_FROM_GLOBAL_ID (val1), - EXTRACT_FUNC_ID_FROM_GLOBAL_ID (val1), (unsigned) count1); + if (flag_ripa_verbose) + { + if (!direct_call1) + inform (locus, "Can not find indirect call target decl " + "(%d:%d)[cnt:%u] in current module", + EXTRACT_MODULE_ID_FROM_GLOBAL_ID (val1), + EXTRACT_FUNC_ID_FROM_GLOBAL_ID (val1), (unsigned) count1); + else + inform (locus, + "Can not find promote indirect call target decl -- type mismatch " + "(%d:%d)[cnt:%u] in current module", + EXTRACT_MODULE_ID_FROM_GLOBAL_ID (val1), + EXTRACT_FUNC_ID_FROM_GLOBAL_ID (val1), (unsigned) count1); + } return false; } @@ -1520,15 +1523,12 @@ gimple_ic_transform_mult_targ (gimple stmt, histogram_value histogram) && ! TREE_PUBLIC (direct_call1->decl)) return false; - inform (locus, "Found indirect call target" - " decl (%d:%d)[cnt:%u] in current module", - EXTRACT_MODULE_ID_FROM_GLOBAL_ID (val1), - EXTRACT_FUNC_ID_FROM_GLOBAL_ID (val1), (unsigned) count1); - - modify1 = gimple_ic (stmt, direct_call1, prob1, count1, all); - inform (locus, "Promote indirect call to target %s", - lang_hooks.decl_printable_name (direct_call1->decl, 3)); + if (flag_ripa_verbose) + inform (locus, "Promote indirect call to target (call count:%u) %s", + (unsigned) count1, + lang_hooks.decl_printable_name (direct_call1->decl, 3)); + if (always_inline && count1 >= always_inline) { /* TODO: should mark the call edge. */ @@ -1541,9 +1541,12 @@ gimple_ic_transform_mult_targ (gimple stmt, histogram_value histogram) print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM); fprintf (dump_file, "=> "); print_generic_expr (dump_file, direct_call1->decl, TDF_SLIM); - fprintf (dump_file, " transformation on insn "); + fprintf (dump_file, " (module_id:%d, func_id:%d)\n", + EXTRACT_MODULE_ID_FROM_GLOBAL_ID (val1), + EXTRACT_FUNC_ID_FROM_GLOBAL_ID (val1)); + fprintf (dump_file, "Transformation on insn:\n"); print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); - fprintf (dump_file, " to "); + fprintf (dump_file, "==>\n"); print_gimple_stmt (dump_file, modify1, 0, TDF_SLIM); fprintf (dump_file, "hist->count "HOST_WIDEST_INT_PRINT_DEC " hist->all "HOST_WIDEST_INT_PRINT_DEC"\n", count1, all); @@ -1559,8 +1562,12 @@ gimple_ic_transform_mult_targ (gimple stmt, histogram_value histogram) { modify2 = gimple_ic (stmt, direct_call2, prob2, count2, all - count1); - inform (locus, "Promote indirect call to target %s", - lang_hooks.decl_printable_name (direct_call2->decl, 3)); + + if (flag_ripa_verbose) + inform (locus, "Promote indirect call to target (call count:%u) %s", + (unsigned) count2, + lang_hooks.decl_printable_name (direct_call2->decl, 3)); + if (always_inline && count2 >= always_inline) { /* TODO: should mark the call edge. */ @@ -1573,9 +1580,12 @@ gimple_ic_transform_mult_targ (gimple stmt, histogram_value histogram) print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM); fprintf (dump_file, "=> "); print_generic_expr (dump_file, direct_call2->decl, TDF_SLIM); - fprintf (dump_file, " transformation on insn "); + fprintf (dump_file, " (module_id:%d, func_id:%d)\n", + EXTRACT_MODULE_ID_FROM_GLOBAL_ID (val2), + EXTRACT_FUNC_ID_FROM_GLOBAL_ID (val2)); + fprintf (dump_file, "Transformation on insn\n"); print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); - fprintf (dump_file, " to "); + fprintf (dump_file, "=>\n"); print_gimple_stmt (dump_file, modify2, 0, TDF_SLIM); fprintf (dump_file, "hist->count "HOST_WIDEST_INT_PRINT_DEC " hist->all "HOST_WIDEST_INT_PRINT_DEC"\n", count2, |