This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

recover -frandom-seed from .rpo file


:ADDPATCH repo:

This is a patch for
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=228769

When the instantiation of symbols involving names in anonymous
namespaces is controlled by -frepo, they will vary from one
compilation to another.  It's not that linking will endless loop, it's
that if you compile, link, then recompile the source, the resulting
.rpo file will use a different seed, which discards all of the useful
instantiate-here information created by the previous link, and then
the next linking will take much longer than it could.

This patch arranges for the random seed to be preserved across
recompilations with -frepo, extracting it from the .rpo file.

I had to delay the initialization of flag_random_seed to this end.  I
thought it would make sense to encapsulate the on-demand
initialization in a function before finding out there were so few
uses.

I've got a small source file that can be used to demonstrate the
problem, but I have no idea about how to fit such a test into our
testsuite, because we need compile, link, recompile then peek at the
.rpo file.  Thoughts?


Ok to install?


Attachment: t.cc
Description: Binary data

for  gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* flags.h (flag_random_seed): Remove declaration, in favor of...
	* toplev.h (get_random_seed, set_random_seed): ... these.
	* tree.c (get_file_function_name): Use the former.
	* opts.c (common_handle_option): Use the latter.
	* toplev.c

for  gcc/cp/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* cp/repo.c (init_repo): Initialize random_seed saved options.
	(finish_repo): Adjust.

Index: gcc/cp/repo.c
===================================================================
--- gcc/cp/repo.c.orig	2007-03-09 07:30:19.000000000 -0300
+++ gcc/cp/repo.c	2007-03-09 07:32:08.000000000 -0300
@@ -1,6 +1,6 @@
 /* Code to maintain a C++ template repository.
-   Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005
-   Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
+   2006, 2007  Free Software Foundation, Inc.
    Contributed by Jason Merrill (jason@cygnus.com)
 
 This file is part of GCC.
@@ -203,6 +203,30 @@ init_repo (void)
       obstack_free (&temporary_obstack, buf);
     }
   fclose (repo_file);
+
+  if (old_args && !get_random_seed (true)
+      && (buf = strstr (old_args, "'-frandom-seed=")))
+    {
+      char *end;
+
+      buf += sizeof ("'-frandom-seed=") - 1;
+
+      for (end = buf; *end; end++)
+	if (end[0] == '\'' && (end[1] == '\0' || end[1] == ' '))
+	  break;
+
+      if (*end)
+	{
+	  char *seed;
+	  size_t len = end - buf;
+
+	  seed = XNEWVEC (char, len + 1);
+	  memcpy (seed, buf, len);
+	  seed[len] = '\0';
+
+	  set_random_seed (seed);
+	}
+    }
 }
 
 static FILE *
@@ -250,7 +274,7 @@ finish_repo (void)
 	 anonymous namespaces will get the same mangling when this
 	 file is recompiled.  */
       if (!strstr (args, "'-frandom-seed="))
-	fprintf (repo_file, " '-frandom-seed=%s'", flag_random_seed);
+	fprintf (repo_file, " '-frandom-seed=%s'", get_random_seed (false));
       fprintf (repo_file, "\n");
     }
 
Index: gcc/flags.h
===================================================================
--- gcc/flags.h.orig	2007-03-09 07:30:19.000000000 -0300
+++ gcc/flags.h	2007-03-09 07:32:08.000000000 -0300
@@ -251,11 +251,6 @@ extern int flag_var_tracking;
    warning message in case flag was set by -fprofile-{generate,use}.  */
 extern bool flag_speculative_prefetching_set;
 
-/* A string that's used when a random name is required.  NULL means
-   to make it really random.  */
-
-extern const char *flag_random_seed;
-
 /* Returns TRUE if generated code should match ABI version N or
    greater is in use.  */
 
Index: gcc/opts.c
===================================================================
--- gcc/opts.c.orig	2007-03-09 07:30:19.000000000 -0300
+++ gcc/opts.c	2007-03-09 07:32:08.000000000 -0300
@@ -1263,11 +1263,11 @@ common_handle_option (size_t scode, cons
       /* The real switch is -fno-random-seed.  */
       if (value)
 	return 0;
-      flag_random_seed = NULL;
+      set_random_seed (NULL);
       break;
 
     case OPT_frandom_seed_:
-      flag_random_seed = arg;
+      set_random_seed (arg);
       break;
 
     case OPT_fsched_verbose_:
Index: gcc/toplev.h
===================================================================
--- gcc/toplev.h.orig	2007-03-09 07:30:19.000000000 -0300
+++ gcc/toplev.h	2007-03-09 07:32:08.000000000 -0300
@@ -1,5 +1,5 @@
 /* toplev.h - Various declarations for functions found in toplev.c
-   Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005
+   Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -191,4 +191,9 @@ exact_log2 (unsigned HOST_WIDE_INT x)
 extern const char *get_src_pwd	       (void);
 extern bool set_src_pwd		       (const char *);
 
+/* Functions used to manipulate the random seed.  */
+
+extern const char *get_random_seed (bool);
+extern const char *set_random_seed (const char *);
+
 #endif /* ! GCC_TOPLEV_H */
Index: gcc/tree.c
===================================================================
--- gcc/tree.c.orig	2007-03-09 07:30:19.000000000 -0300
+++ gcc/tree.c	2007-03-09 07:32:08.000000000 -0300
@@ -6497,7 +6497,7 @@ get_file_function_name (const char *type
       clean_symbol_name (q);
 
       sprintf (q + len, "_%08X_%08X", crc32_string (0, name),
-	       crc32_string (0, flag_random_seed));
+	       crc32_string (0, get_random_seed (false)));
 
       p = q;
     }
Index: gcc/toplev.c
===================================================================
--- gcc/toplev.c.orig	2007-03-09 07:30:19.000000000 -0300
+++ gcc/toplev.c	2007-03-09 07:58:43.000000000 -0300
@@ -1,6 +1,6 @@
 /* Top level of GCC compilers (cc1, cc1plus, etc.)
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -239,7 +239,7 @@ int in_system_header = 0;
 int flag_detailed_statistics = 0;
 
 /* A random sequence of characters, unless overridden by user.  */
-const char *flag_random_seed;
+static const char *flag_random_seed;
 
 /* A local time stamp derived from the time of compilation. It will be
    zero if the system cannot provide a time.  It will be -1u, if the
@@ -451,23 +451,20 @@ announce_function (tree decl)
     }
 }
 
-/* Set up a default flag_random_seed and local_tick, unless the user
-   already specified one.  */
+/* Initialize local_tick with the time of day, or -1 if
+   flag_random_seed is set.  */
 
 static void
-randomize (void)
+init_local_tick (void)
 {
   if (!flag_random_seed)
     {
-      unsigned HOST_WIDE_INT value;
-      static char random_seed[HOST_BITS_PER_WIDE_INT / 4 + 3];
-
       /* Get some more or less random data.  */
 #ifdef HAVE_GETTIMEOFDAY
       {
- 	struct timeval tv;
+	struct timeval tv;
 
- 	gettimeofday (&tv, NULL);
+	gettimeofday (&tv, NULL);
 	local_tick = tv.tv_sec * 1000 + tv.tv_usec / 1000;
       }
 #else
@@ -478,15 +475,47 @@ randomize (void)
 	  local_tick = (unsigned) now;
       }
 #endif
-      value = local_tick ^ getpid ();
-
-      sprintf (random_seed, HOST_WIDE_INT_PRINT_HEX, value);
-      flag_random_seed = random_seed;
     }
-  else if (!local_tick)
+  else
     local_tick = -1;
 }
 
+/* Set up a default flag_random_seed and local_tick, unless the user
+   already specified one.  Must be called after init_local_tick.  */
+
+static void
+init_random_seed (void)
+{
+  unsigned HOST_WIDE_INT value;
+  static char random_seed[HOST_BITS_PER_WIDE_INT / 4 + 3];
+
+  value = local_tick ^ getpid ();
+
+  sprintf (random_seed, HOST_WIDE_INT_PRINT_HEX, value);
+  flag_random_seed = random_seed;
+}
+
+/* Obtain the random_seed string.  Unless NOINIT, initialize it if
+   it's not provided in the command line.  */
+
+const char *
+get_random_seed (bool noinit)
+{
+  if (!flag_random_seed && !noinit)
+    init_random_seed ();
+  return flag_random_seed;
+}
+
+/* Modify the random_seed string to VAL.  Return its previous
+   value.  */
+
+const char *
+set_random_seed (const char *val)
+{
+  const char *old = flag_random_seed;
+  flag_random_seed = val;
+  return old;
+}
 
 /* Decode the string P as an integral parameter.
    If the string is indeed an integer return its numeric value else
@@ -1277,7 +1306,8 @@ print_switch_values (print_switch_fn_typ
 
   /* Fill in the -frandom-seed option, if the user didn't pass it, so
      that it can be printed below.  This helps reproducibility.  */
-  randomize ();
+  if (!flag_random_seed)
+    init_random_seed ();
 
   /* Print the options as passed.  */
   pos = print_single_switch (print_fn, pos,
@@ -2119,7 +2149,7 @@ toplev_main (unsigned int argc, const ch
      enough to default flags appropriately.  */
   decode_options (argc, argv);
 
-  randomize ();
+  init_local_tick ();
 
   /* Exit early if we can (e.g. -help).  */
   if (!exit_after_options)

-- 
Alexandre Oliva         http://www.lsd.ic.unicamp.br/~oliva/
FSF Latin America Board Member         http://www.fsfla.org/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]