OSDN Git Service

Speed up genmultilib; Add MULTIB_EXTRA_OPTS
authormeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 12 Aug 1996 16:36:42 +0000 (16:36 +0000)
committermeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 12 Aug 1996 16:36:42 +0000 (16:36 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@12623 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/Makefile.in
gcc/gcc.c
gcc/genmultilib

index 76616a8..71e8971 100644 (file)
@@ -550,7 +550,7 @@ CCCP=cccp
 STAGESTUFF = *$(objext) insn-flags.h insn-config.h insn-codes.h \
  insn-output.c insn-recog.c insn-emit.c insn-extract.c insn-peep.c \
  insn-attr.h insn-attrtab.c insn-opinit.c \
- stamp-flags stamp-config stamp-codes \
+ stamp-flags stamp-config stamp-codes stamp-mlib \
  stamp-output stamp-recog stamp-emit stamp-extract stamp-peep \
  stamp-attr stamp-attrtab stamp-opinit stamp-proto stamp-crt stamp-crtS stamp-crt0 \
  genemit$(exeext) genoutput$(exeext) genrecog$(exeext) genextract$(exeext) \
@@ -955,9 +955,16 @@ libgcc.a: $(LIBGCC1) $(LIBGCC2)
 # Use the genmultilib shell script to generate the information the gcc
 # driver program needs to select the library directory based on the
 # switches.
-multilib.h: $(srcdir)/genmultilib Makefile
-       $(SHELL) $(srcdir)/genmultilib "$(MULTILIB_OPTIONS)" \
-         "$(MULTILIB_DIRNAMES)" "$(MULTILIB_MATCHES)" "$(MULTILIB_EXCEPTIONS)" > multilib.h
+multilib.h: stamp-mlib; @true
+stamp-mlib: $(srcdir)/genmultilib Makefile
+       $(SHELL) $(srcdir)/genmultilib \
+         "$(MULTILIB_OPTIONS)" \
+         "$(MULTILIB_DIRNAMES)" \
+         "$(MULTILIB_MATCHES)" \
+         "$(MULTILIB_EXCEPTIONS)" \
+         "$(MULTILIB_EXTRA_OPTS)" > tmp-mlib.h
+       $(srcdir)/move-if-change tmp-mlib.h multilib.h
+       touch stamp-mlib
 
 # Build multiple copies of libgcc.a, one for each target switch.
 stmp-multilib: $(LIBGCC1) libgcc2.c libgcc2.ready $(CONFIG_H) \
index 940c8e8..46ca22b 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -491,12 +491,21 @@ static char *startfile_spec = STARTFILE_SPEC;
 static char *switches_need_spaces = SWITCHES_NEED_SPACES;
 
 /* Some compilers have limits on line lengths, and the multilib_select
-   string can be very long, so we build it at run time.  */
+   and/or multilib_matches strings can be very long, so we build them at
+   run time.  */
 static struct obstack multilib_obstack;
-static char *multilib_raw[] = {
-#include "multilib.h"
-};
 static char *multilib_select;
+static char *multilib_matches;
+static char *multilib_defaults;
+#include "multilib.h"
+
+/* Check whether a particular argument is a default argument.  */
+
+#ifndef MULTILIB_DEFAULTS
+#define MULTILIB_DEFAULTS { "" }
+#endif
+
+static char *multilib_defaults_raw[] = MULTILIB_DEFAULTS;
 
 #ifdef EXTRA_SPECS
 static struct { char *name, *spec; } extra_specs[] = { EXTRA_SPECS };
@@ -1223,6 +1232,12 @@ set_spec (name, spec)
     cross_compile = atoi (sl->spec);
   else if (! strcmp (name, "multilib"))
     multilib_select = sl->spec;
+  else if (! strcmp (name, "multilib_matches"))
+    multilib_matches = sl->spec;
+  else if (! strcmp (name, "multilib_extra"))
+    multilib_extra = sl->spec;
+  else if (! strcmp (name, "multilib_defaults"))
+    multilib_defaults = sl->spec;
 #ifdef EXTRA_SPECS
   else
     {
@@ -2244,6 +2259,9 @@ process_command (argc, argv)
          printf ("*predefines:\n%s\n\n", cpp_predefines);
          printf ("*cross_compile:\n%d\n\n", cross_compile);
          printf ("*multilib:\n%s\n\n", multilib_select);
+         printf ("*multilib_defaults:\n%s\n\n", multilib_defaults);
+         printf ("*multilib_extra:\n%s\n\n", multilib_extra);
+         printf ("*multilib_matches:\n%s\n\n", multilib_matches);
 
 #ifdef EXTRA_SPECS
          {
@@ -4027,10 +4045,11 @@ main (argc, argv)
 
   obstack_init (&obstack);
 
-  /* Build multilib_select from the separate lines that make up each multilib
-     selection.  */
+  /* Build multilib_select, et. al from the separate lines that make up each
+     multilib selection.  */
   {
     char **q = multilib_raw;
+    int need_space;
 
     obstack_init (&multilib_obstack);
     while ((p = *q++) != (char *) 0)
@@ -4038,6 +4057,29 @@ main (argc, argv)
 
     obstack_1grow (&multilib_obstack, 0);
     multilib_select = obstack_finish (&multilib_obstack);
+
+    q = multilib_matches_raw;
+    while ((p = *q++) != (char *) 0)
+      obstack_grow (&multilib_obstack, p, strlen (p));
+
+    obstack_1grow (&multilib_obstack, 0);
+    multilib_matches = obstack_finish (&multilib_obstack);
+
+    need_space = FALSE;
+    for (i = 0;
+        i < sizeof (multilib_defaults_raw) / sizeof (multilib_defaults_raw[0]);
+        i++)
+      {
+       if (need_space)
+         obstack_1grow (&multilib_obstack, ' ');
+       obstack_grow (&multilib_obstack,
+                     multilib_defaults_raw[i],
+                     strlen (multilib_defaults_raw[i]));
+       need_space = TRUE;
+      }
+
+    obstack_1grow (&multilib_obstack, 0);
+    multilib_defaults = obstack_finish (&multilib_obstack);
   }
 
   /* Set up to remember the pathname of gcc and any options
@@ -4825,43 +4867,114 @@ validate_switches (start)
     }
 }
 \f
-/* Check whether a particular argument was used.  */
+/* Check whether a particular argument was used.  The first time we
+   canonialize the switches to keep only the ones we care about.  */
 
 static int
 used_arg (p, len)
      char *p;
      int len;
 {
-  int i;
+  struct mswitchstr {
+    char *str;
+    char *replace;
+    int len;
+    int rep_len;
+  };
+
+  static struct mswitchstr *mswitches;
+  static int n_mswitches;
+  int i, j;
+
+  if (!mswitches)
+    {
+      struct mswitchstr *matches;
+      char *q;
+      int cnt = (*multilib_matches != '\0');
+
+      /* Break multilib_matches into the component strings of string and replacement
+         string */
+      for (p = multilib_matches; *p != '\0'; p++)
+       if (*p == ';')
+         cnt++;
+
+      matches = (struct mswitchstr *) alloca ((sizeof (struct mswitchstr)) * cnt);
+      i = 0;
+      q = multilib_matches;
+      while (*q != '\0')
+       {
+         matches[i].str = q;
+         while (*q != ' ')
+           {
+             if (*q == '\0')
+               abort ();
+             q++;
+           }
+         *q = '\0';
+         matches[i].len = q - matches[i].str;
 
-  for (i = 0; i < n_switches; i++)
-    if (! strncmp (switches[i].part1, p, len)
-       && strlen (switches[i].part1) == len)
-      return 1;
-  return 0;
-}
+         matches[i].replace = ++q;
+         while (*q != ';' && *q != '\0')
+           {
+             if (*q == ' ')
+               abort ();
+             q++;
+           }
+         matches[i].rep_len = q - matches[i].replace;
+         i++;
+         if (*q == ';')
+           *q++ = '\0';
+         else
+           break;
+       }
 
-/* Check whether a particular argument is a default argument.  */
+      /* Now build a list of the replacement string for switches that we care about */
+      mswitches = (struct mswitchstr *) xmalloc ((sizeof (struct mswitchstr)) * n_switches);
+      for (i = 0; i < n_switches; i++)
+       {
+         int xlen = strlen (switches[i].part1);
+         for (j = 0; j < cnt; j++)
+           if (xlen == matches[j].len && ! strcmp (switches[i].part1, matches[j].str))
+             {
+               mswitches[n_mswitches].str = matches[j].replace;
+               mswitches[n_mswitches].len = matches[j].rep_len;
+               mswitches[n_mswitches].replace = (char *)0;
+               mswitches[n_mswitches].rep_len = 0;
+               n_mswitches++;
+               break;
+             }
+       }
+    }
 
-#ifndef MULTILIB_DEFAULTS
-#define MULTILIB_DEFAULTS { NULL }
-#endif
+  for (i = 0; i < n_mswitches; i++)
+    if (len == mswitches[i].len && ! strncmp (p, mswitches[i].str, len))
+      return 1;
 
-static char *multilib_defaults[] = MULTILIB_DEFAULTS;
+  return 0;
+}
 
 static int
 default_arg (p, len)
      char *p;
      int len;
 {
-  int count = sizeof multilib_defaults / sizeof multilib_defaults[0];
+  char *start, *end;
   int i;
 
-  for (i = 0; i < count; i++)
-    if (multilib_defaults[i] != NULL
-       && strncmp (multilib_defaults[i], p, len) == 0
-       && multilib_defaults[i][len] == '\0')
-      return 1;
+  for (start = multilib_defaults; *start != '\0'; start = end+1)
+    {
+      while (*start == ' ' || *start == '\t')
+       start++;
+
+      if (*start == '\0')
+       break;
+
+      for (end = start+1; *end != ' ' && *end != '\t' && *end != '\0'; end++)
+       ;
+
+      if ((end - start) == len && strncmp (p, start, len) == 0)
+       return 1;
+    }
 
   return 0;
 }
@@ -5089,7 +5202,28 @@ print_multilib_info ()
        }
 
       if (! skip)
-       putchar ('\n');
+       {
+         /* If there are extra options, print them now */
+         if (multilib_extra && *multilib_extra)
+           {
+             int print_at = TRUE;
+             char *q;
+
+             for (q = multilib_extra; *q != '\0'; q++)
+               {
+                 if (*q == ' ')
+                   print_at = TRUE;
+                 else
+                   {
+                     if (print_at)
+                       putchar ('@');
+                     putchar (*q);
+                     print_at = FALSE;
+                   }
+               }
+           }
+         putchar ('\n');
+       }
 
       ++p;
     }
index e66106f..1ae690b 100644 (file)
@@ -1,6 +1,6 @@
 #!/bin/sh 
 # Generates multilib.h.
-#   Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+#   Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
 
 #This file is part of GNU CC.
 
@@ -45,6 +45,9 @@
 # The optional fourth argument is a list of multilib directory 
 # combinations that should not be built.
 
+# The optional fifth argument is a list of options that should be
+# used whenever building multilib libraries.
+
 # The output looks like
 #   #define MULTILIB_MATCHES "\
 #   SUBDIRECTORY OPTIONS;\
@@ -81,6 +84,9 @@ options=$1
 dirnames=$2
 matches=$3
 exceptions=$4
+extra=$5
+
+echo "static char *multilib_raw[] = {"
 
 # What we want to do is select all combinations of the sets in
 # options.  Each combination which includes a set of mutually
@@ -158,16 +164,6 @@ if [ -n "${dirnames}" ]; then
   done
 fi
 
-# Construct a sed pattern which will add negations based on the
-# matches.  The semicolons are easier than getting the shell to accept
-# quoted spaces when expanding a variable.
-matchnegations=
-for i in ${matches}; do
-  l=`echo $i | sed -e 's/=.*$//' -e 's/?/=/g'`
-  r=`echo $i | sed -e 's/^.*=//' -e 's/?/=/g'`
-  matchnegations="${matchnegations} -e s/;!${l};/;!${l};!${r};/"
-done
-
 # We need another recursive shell script to correctly handle positive
 # matches.  If we are invoked as
 #   genmultilib "opt1 opt2" "" "opt1=nopt1 opt2=nopt2"
@@ -207,9 +203,6 @@ for set in ${options}; do
   done
 done
 optout=`echo ${optout} | sed -e 's/^ //'`
-if [ -n "${matchnegations}" ]; then
-  optout=`echo ";${optout};" | sed -e 's/ /;/g' ${matchnegations} -e 's/^;//' -e 's/;$//' -e 's/;/ /g'`
-fi
 echo "\". ${optout};\","
 
 # Work over the list of combinations.  We have to translate each one
@@ -241,18 +234,36 @@ for combo in ${combinations}; do
   done
   optout=`echo ${optout} | sed -e 's/^ //'`
 
-  # Add any negations of matches.
-  if [ -n "${matchnegations}" ]; then
-    optout=`echo ";${optout};" | sed -e 's/ /;/g' ${matchnegations} -e 's/^;//' -e 's/;$//' -e 's/;/ /g'`
-  fi
-
   # Output the line with all appropriate matches.
-  dirout="${dirout}" optout="${optout}" ./tmpmultilib2 ${matches}
+  dirout="${dirout}" optout="${optout}" ./tmpmultilib2
 done
 
 # Terminate the list of string.
 echo "NULL"
+echo "};"
+
+# Output all of the matches now as option and that is the same as that, with
+# a semicolan trailer.  Include all of the normal options as well.
+# Note, the format of the matches is reversed compared
+# to what we want, so switch them around.
+echo ""
+echo "static char *multilib_matches_raw[] = {"
+for match in ${matches}; do
+  l=`echo ${match} | sed -e 's/=.*$//' -e 's/?/=/g'`
+  r=`echo ${match} | sed -e 's/^.*=//' -e 's/?/=/g'`
+  echo "\"${r} ${l};\","
+done
+for set in ${options}; do
+  for opt in `echo ${set} | sed -e 's|/| |'g`; do
+    echo "\"${opt} ${opt};\","
+  done
+done
+echo "NULL"
+echo "};"
 
+# Output the default options now
+echo ""
+echo "static char *multilib_extra = \"${extra}\";"
 rm -f tmpmultilib2
 
 exit 0