aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorraksit <raksit@138bc75d-0d04-0410-961f-82ee72b054a4>2010-04-25 09:18:10 +0000
committerraksit <raksit@138bc75d-0d04-0410-961f-82ee72b054a4>2010-04-25 09:18:10 +0000
commite19b94bb4bb709ff7a04ec9656f2761bbf8924fe (patch)
tree316099f8fd8a0f7048e037179ea6e0235cee24f5
parentafa21ffa4e3713f33b4a3f76e9b3bc9862af9929 (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.in2
-rw-r--r--gcc/c-opts.c6
-rw-r--r--gcc/cfg.c20
-rw-r--r--gcc/common.opt8
-rw-r--r--gcc/coverage.c162
-rw-r--r--gcc/coverage.h3
-rw-r--r--gcc/cp/cp-objcp-common.c8
-rw-r--r--gcc/doc/invoke.texi19
-rw-r--r--gcc/dyn-ipa.c6
-rw-r--r--gcc/gcov-io.c6
-rw-r--r--gcc/gcov-io.h13
-rw-r--r--gcc/opts.h1
-rw-r--r--gcc/profile.c1
-rw-r--r--gcc/stmt.c2
-rw-r--r--gcc/tree-inline.c15
-rw-r--r--gcc/value-prof.c60
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,