[lipo] [patch, committed] bug fixes

Raksit Ashok raksit@google.com
Sun Apr 25 09:42:00 GMT 2010


Hi,

I committed another round of bug-fixes as revision 158700, after
bootstrapping and regtesting on x86-64-unknown-linux-gnu:
* 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).

thanks,
raksit
-------------- next part --------------
Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 158698)
+++ gcc/doc/invoke.texi	(working copy)
@@ -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 dynami
 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
Index: gcc/dyn-ipa.c
===================================================================
--- gcc/dyn-ipa.c	(revision 158698)
+++ gcc/dyn-ipa.c	(working copy)
@@ -1055,7 +1055,8 @@ gcov_write_module_info (const struct gco
   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 gco
       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 gco
   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 */
Index: gcc/value-prof.c
===================================================================
--- gcc/value-prof.c	(revision 158698)
+++ gcc/value-prof.c	(working copy)
@@ -1498,17 +1498,20 @@ gimple_ic_transform_mult_targ (gimple st
   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 st
       && ! 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 st
       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 st
     {
       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 st
           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,
Index: gcc/cfg.c
===================================================================
--- gcc/cfg.c	(revision 158698)
+++ gcc/cfg.c	(working copy)
@@ -1042,7 +1042,7 @@ scale_bbs_frequencies_int (basic_block *
       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 *
       /* 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_b
 {
   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_b
 	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_b
 	  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);
       }
 }
 
Index: gcc/cp/cp-objcp-common.c
===================================================================
--- gcc/cp/cp-objcp-common.c	(revision 158698)
+++ gcc/cp/cp-objcp-common.c	(working copy)
@@ -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));
     }
 }
 
Index: gcc/gcov-io.c
===================================================================
--- gcc/gcov-io.c	(revision 158698)
+++ gcc/gcov-io.c	(working copy)
@@ -512,8 +512,9 @@ gcov_read_module_info (struct gcov_modul
   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_modul
   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 ();
Index: gcc/gcov-io.h
===================================================================
--- gcc/gcov-io.h	(revision 158698)
+++ gcc/gcov-io.h	(working copy)
@@ -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.  */
Index: gcc/opts.h
===================================================================
--- gcc/opts.h	(revision 158698)
+++ gcc/opts.h	(working copy)
@@ -121,4 +121,5 @@ extern void add_input_filename (const ch
 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
Index: gcc/profile.c
===================================================================
--- gcc/profile.c	(revision 158698)
+++ gcc/profile.c	(working copy)
@@ -283,6 +283,7 @@ is_edge_inconsistent (VEC(edge,gc) *edge
         {
           if (e->count < 0
 	      && (!(e->flags & EDGE_FAKE)
+		  || e->src == ENTRY_BLOCK_PTR
 	          || !block_ends_with_call_p (e->src)))
 	    {
 	      if (dump_file)
Index: gcc/coverage.c
===================================================================
--- gcc/coverage.c	(revision 158698)
+++ gcc/coverage.c	(working copy)
@@ -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 = fal
 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
   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_na
 		     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_na
 	      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_na
 	      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_na
 		}
             }
 
-	  /* 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, u
 
   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_
   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_r
 	  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, con
   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"
Index: gcc/coverage.h
===================================================================
--- gcc/coverage.h	(revision 158698)
+++ gcc/coverage.h	(working copy)
@@ -66,4 +66,7 @@ extern bool coverage_function_present (u
 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
Index: gcc/c-opts.c
===================================================================
--- gcc/c-opts.c	(revision 158698)
+++ gcc/c-opts.c	(working copy)
@@ -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)
Index: gcc/common.opt
===================================================================
--- gcc/common.opt	(revision 158698)
+++ gcc/common.opt	(working copy)
@@ -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
Index: gcc/tree-inline.c
===================================================================
--- gcc/tree-inline.c	(revision 158698)
+++ gcc/tree-inline.c	(working copy)
@@ -1474,7 +1474,7 @@ copy_bb (copy_body_data *id, basic_block
      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_
 	    && 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 c
   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 c
 
   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
   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;
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in	(revision 158698)
+++ gcc/Makefile.in	(working copy)
@@ -2775,7 +2775,7 @@ stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_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 \
Index: gcc/stmt.c
===================================================================
--- gcc/stmt.c	(revision 158698)
+++ gcc/stmt.c	(working copy)
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  
 #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 o
       emit_move_insn (real_output_rtx[i], output_rtx[i]);
 
   crtl->has_asm_statement = 1;
+  coverage_has_asm_stmt ();
   free_temp_slots ();
 }
 


More information about the Gcc-patches mailing list