public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFC] New feature to reuse one multilib among different targets
@ 2012-10-10  7:58 Terry Guo
  2012-10-10 14:59 ` Joseph S. Myers
  0 siblings, 1 reply; 13+ messages in thread
From: Terry Guo @ 2012-10-10  7:58 UTC (permalink / raw)
  To: joseph; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 2019 bytes --]

Hello Joseph,

Please help to review this new Multilib feature. It intends to provide user
a chance to define their own multilib selection rules. Those rules will be
appended to rules generated by gcc script genmultilib. Thus when gcc can't
find suitable multilib from its own rules, it can fall back to certain
existing multilib according to rules provided by user. This feature is
called multilib reuse.

With multilib reuse, we can link a better multilib rather than always using
the default multilib when fail to find exactly matched multilib. This
feature also can help to reduce the total number of multilib variants.

For simplicity, the rules used by multilib reuse are same with the rules in
variable multilib_select. For example, to reuse multilib (in folder dirM and
built with option "optA optB optC") among targets "optA optD optE" and "optA
optF optG", we can define following reuse rules:

MULTILIB_REUSE = dirM optA optD optE;dirM optA optF optG;

The above method requires user to define such rules in Multilib Makefile
fragment and those rules are eventually turned into gcc built-in rules. Any
change to them require to rebuild the gcc. To make it easy to adjust reuse
rules, my patch turns MULTILIB_REUSE into a gcc spec named multilib_reuse.
So follow the way how gcc handle spec, it's easy to change reuse rules
without rebuilding the gcc. Suppose we need to share same multilib with
target "optH optI optJ", we can write following spec file and feed it to
gcc:

*multilib_reuse:
+ dirM optH optI optJ;

In summary, we can use fragment to provide some pre-decided rules and use
spec to change rules on the fly.

Does this feature make sense and is it ok to trunk? Please advise. Thanks.

BR,
Terry

2012-10-10  Terry Guo  <terry.guo@arm.com>

        * genmultilib (MULTILIB_REUSE): New macro.
        * Makefile.in (s-mlib): Add a new argument MULTILIB_REUSE.
        * gcc.c (multilib_reuse): New spec.
        (set_multilib_dir): Use multilib_reuse.

[-- Attachment #2: gcc-multilib-reuse.patch --]
[-- Type: application/octet-stream, Size: 4027 bytes --]

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 9376e00..82986a8 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1800,10 +1800,11 @@ s-mlib: $(srcdir)/genmultilib Makefile
 	    "$(MULTILIB_EXCLUSIONS)" \
 	    "$(MULTILIB_OSDIRNAMES)" \
 	    "$(MULTILIB_REQUIRED)" \
+	    "$(MULTILIB_REUSE)" \
 	    "@enable_multilib@" \
 	    > tmp-mlib.h; \
 	else \
-	  $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' '' '' no\
+	  $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' '' '' '' no\
 	    > tmp-mlib.h; \
 	fi
 	$(SHELL) $(srcdir)/../move-if-change tmp-mlib.h multilib.h
diff --git a/gcc/gcc.c b/gcc/gcc.c
index bbca6d8..94f29f1 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -1212,6 +1212,7 @@ static struct spec_list static_specs[] =
   INIT_STATIC_SPEC ("multilib_matches",		&multilib_matches),
   INIT_STATIC_SPEC ("multilib_exclusions",	&multilib_exclusions),
   INIT_STATIC_SPEC ("multilib_options",		&multilib_options),
+  INIT_STATIC_SPEC ("multilib_reuse",		&multilib_reuse),
   INIT_STATIC_SPEC ("linker",			&linker_name_spec),
   INIT_STATIC_SPEC ("linker_plugin_file",	&linker_plugin_file_spec),
   INIT_STATIC_SPEC ("lto_wrapper",		&lto_wrapper_spec),
@@ -7471,10 +7472,16 @@ set_multilib_dir (void)
 
   first = 1;
   p = multilib_select;
+
+  /* Append multilib reuse rules if any.  With those rules, we can reuse
+     one multilib for certain different targets.  */
+  if (strlen(multilib_reuse) > 0)
+    p = concat (p, multilib_reuse, NULL);
+
   while (*p != '\0')
     {
-      /* Ignore newlines.  */
-      if (*p == '\n')
+      /* Ignore newlines and spaces.  */
+      if (*p == '\n' || *p == ' ')
 	{
 	  ++p;
 	  continue;
@@ -7487,8 +7494,8 @@ set_multilib_dir (void)
 	  if (*p == '\0')
 	    {
 	    invalid_select:
-	      fatal_error ("multilib select %qs is invalid",
-			   multilib_select);
+	      fatal_error ("multilib select %qs%qs is invalid",
+			   multilib_select, multilib_reuse);
 	    }
 	  ++p;
 	}
diff --git a/gcc/genmultilib b/gcc/genmultilib
index dc4751b..fca24db 100644
--- a/gcc/genmultilib
+++ b/gcc/genmultilib
@@ -84,6 +84,15 @@
 # This argument can be used together with MULTILIB_EXCEPTIONS and will take
 # effect after the MULTILIB_EXCEPTIONS.
 
+# The optional ninth argument is a set of predefined multilib selection rules
+# which will be appended to variable multilib_select defined in gcc.c and can
+# eventually impact how gcc selects multilib.  The rules in this argument will
+# be used only when gcc can't find suitable multilib from multilib_select.
+# This argument enables us to reuse one multilib among certain targets,
+# for example we can reuse multilib built with options "optA optB optC"
+# among options "optA optD optE" and "optA optF optG" with rules:
+# dirA optA optB optC;dirA optA optD optE;dirA optA optF optG;
+
 # The last option should be "yes" if multilibs are enabled.  If it is not
 # "yes", all GCC multilib dir names will be ".".
 
@@ -104,7 +113,7 @@
 #   genmultilib 'm64/m32 mno-app-regs|mcmodel=medany' '64 32 alt'
 #		'mcmodel?medany=mcmodel?medmid' 'm32/mno-app-regs* m32/mcmodel=*'
 #		'' 'm32/!m64/mno-app-regs m32/!m64/mcmodel=medany'
-#		'../lib64 ../lib32 alt' '' yes
+#		'../lib64 ../lib32 alt' '' '' yes
 # This produces:
 #   ". !m64 !m32 !mno-app-regs !mcmodel=medany;",
 #   "64:../lib64 m64 !m32 !mno-app-regs !mcmodel=medany;",
@@ -133,7 +142,8 @@ extra=$5
 exclusions=$6
 osdirnames=$7
 multilib_required=$8
-enable_multilib=$9
+multilib_reuse=$9
+enable_multilib=${10}
 
 echo "static const char *const multilib_raw[] = {"
 
@@ -443,6 +453,10 @@ moptions=`echo ${options} | sed -e 's,[ 	][ 	]*, ,g'`
 echo ""
 echo "static const char *multilib_options = \"${moptions}\";"
 
+# Output the multilib reuse rules now
+echo ""
+echo "static const char *multilib_reuse = \"${multilib_reuse}\";"
+
 # Finally output the disable flag if specified
 if [ "x${disable_multilib}" = xyes ]; then
   echo ""

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [RFC] New feature to reuse one multilib among different targets
  2012-10-10  7:58 [RFC] New feature to reuse one multilib among different targets Terry Guo
@ 2012-10-10 14:59 ` Joseph S. Myers
  2012-11-08  1:37   ` Terry Guo
  0 siblings, 1 reply; 13+ messages in thread
From: Joseph S. Myers @ 2012-10-10 14:59 UTC (permalink / raw)
  To: Terry Guo; +Cc: gcc-patches

On Wed, 10 Oct 2012, Terry Guo wrote:

> Hello Joseph,
> 
> Please help to review this new Multilib feature. It intends to provide user

Your patch doesn't include documentation for fragments.texi (which needs 
to define the semantics without reference to the details of what gcc.c's 
internal datastructures for multilibs, as output by genmultilib, might 
look like).

I am unconvinced that directly adding to the drivers' internal 
datastructures like this is a sensible interface for specifying multilib 
choice in target makefile fragments.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: [RFC] New feature to reuse one multilib among different targets
  2012-10-10 14:59 ` Joseph S. Myers
@ 2012-11-08  1:37   ` Terry Guo
  2012-11-08 21:11     ` Joseph S. Myers
  0 siblings, 1 reply; 13+ messages in thread
From: Terry Guo @ 2012-11-08  1:37 UTC (permalink / raw)
  To: joseph; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1768 bytes --]


[...]
> > Please help to review this new Multilib feature. It intends to
> provide
> > user
> 
> Your patch doesn't include documentation for fragments.texi (which
> needs to define the semantics without reference to the details of what
> gcc.c's internal datastructures for multilibs, as output by genmultilib,
> might look like).
> 
> I am unconvinced that directly adding to the drivers' internal
> datastructures like this is a sensible interface for specifying
> multilib choice in target makefile fragments.
> 

Very appreciate your review and comments. Here is an updated patch which
follows the approaches used in current multilib implementation. With this
update, the following statement means target represented by "optC optD" can
reuse existing multilib built by options "optA optB":

MULTILIB_REUSE = optA/optB=optC/optD

To convert such statements to data structure used by multilib_raw, I
refactor codes in genmultilib into two functions combo_to_dir and
options_output. Then use combo_to_dir to convert left part into multilib
folder name and use options_output to convert right part into option list.

Inside gcc.c, those reuse rules will be used once gcc can't figure out
multilib that exactly matches current command line options.

I build trunk code with this patch along with --enable-multilib for targets
arm-none-eabi/x86/m6800/mips/powerpc. No problem found.

Is this patch OK? Please comment.

BR,
Terry

2012-11-08  Terry Guo  <terry.guo@arm.com>

	* genmultilib (combo_to_dir): New function.
	(options_output): New function.
	(MULTILIB_REUSE): New argument.
	* Makefile.in (s-mlib): Add a new argument MULTILIB_REUSE.
	* gcc.c (multilib_reuse): New spec.
	(set_multilib_dir): Use multilib_reuse.

[-- Attachment #2: multilib-reuse-v2.patch --]
[-- Type: application/octet-stream, Size: 8827 bytes --]

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 96765fe..6c88e60 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1809,10 +1809,11 @@ s-mlib: $(srcdir)/genmultilib Makefile
 	    "$(MULTILIB_EXCLUSIONS)" \
 	    "$(MULTILIB_OSDIRNAMES)" \
 	    "$(MULTILIB_REQUIRED)" \
+	    "$(MULTILIB_REUSE)" \
 	    "@enable_multilib@" \
 	    > tmp-mlib.h; \
 	else \
-	  $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' '' '' no\
+	  $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' '' '' '' no\
 	    > tmp-mlib.h; \
 	fi
 	$(SHELL) $(srcdir)/../move-if-change tmp-mlib.h multilib.h
diff --git a/gcc/doc/fragments.texi b/gcc/doc/fragments.texi
index f53df29..eeaefb0 100644
--- a/gcc/doc/fragments.texi
+++ b/gcc/doc/fragments.texi
@@ -144,6 +144,28 @@ The @code{MULTILIB_REQUIRED} can be used together with
 @code{MULTILIB_OPTIONS} will be filtered by @code{MULTILIB_EXCEPTIONS}
 and then by @code{MULTILIB_REQUIRED}.
 
+@findex MULTILIB_REUSE
+@item MULTILIB_REUSE
+Sometimes it is desirable to reuse one existing multilib among different
+targets.  Such kind of reuse can minimize the number of multilib variants.
+Also for some targets it is better to reuse an existing multilib than to
+fall back on default multilib when there is no corresponding multilib.  To
+achieve this, just set @code{MULTILIB_REUSE} to the list of reuse rules.
+A typical reuse rule is comprised of two parts connected by equality sign.
+The left part of the rule are the options used to build multilib and the right
+part are the options representing target that will reuse this multilib.  The
+equality sign in both parts should be replaced with period.
+The @code{MULTILIB_REUSE} is different from @code{MULTILIB_MATCHES} in that it
+sets up relations between two option sets rather than two options.  Here is an
+example to demo how we reuse libraries built in Thumb mode for applications built
+in ARM mode:
+@smallexample
+@code{MULTILIB_REUSE} = mthumb/march.armv7-r=marm/march.armv7-r
+@end smallexample
+
+The @code{MULTILIB_REUSE} is a complementary way to select multilib.  Only when the
+original way fails it will work.
+
 @findex MULTILIB_EXTRA_OPTS
 @item MULTILIB_EXTRA_OPTS
 Sometimes it is desirable that when building multiple versions of
diff --git a/gcc/gcc.c b/gcc/gcc.c
index bbca6d8..d06b40d 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -822,6 +822,7 @@ static const char *multilib_select;
 static const char *multilib_matches;
 static const char *multilib_defaults;
 static const char *multilib_exclusions;
+static const char *multilib_reuse;
 
 /* Check whether a particular argument is a default argument.  */
 
@@ -1212,6 +1213,7 @@ static struct spec_list static_specs[] =
   INIT_STATIC_SPEC ("multilib_matches",		&multilib_matches),
   INIT_STATIC_SPEC ("multilib_exclusions",	&multilib_exclusions),
   INIT_STATIC_SPEC ("multilib_options",		&multilib_options),
+  INIT_STATIC_SPEC ("multilib_reuse",		&multilib_reuse),
   INIT_STATIC_SPEC ("linker",			&linker_name_spec),
   INIT_STATIC_SPEC ("linker_plugin_file",	&linker_plugin_file_spec),
   INIT_STATIC_SPEC ("lto_wrapper",		&lto_wrapper_spec),
@@ -6269,6 +6271,13 @@ main (int argc, char **argv)
     obstack_1grow (&multilib_obstack, 0);
     multilib_exclusions = XOBFINISH (&multilib_obstack, const char *);
 
+    q = multilib_reuse_raw;
+    while ((p = *q++) != (char *) 0)
+      obstack_grow (&multilib_obstack, p, strlen (p));
+
+    obstack_1grow (&multilib_obstack, 0);
+    multilib_reuse = XOBFINISH (&multilib_obstack, const char *);
+
     need_space = FALSE;
     for (i = 0; i < ARRAY_SIZE (multilib_defaults_raw); i++)
       {
@@ -7471,10 +7480,16 @@ set_multilib_dir (void)
 
   first = 1;
   p = multilib_select;
+
+  /* Append multilib reuse rules if any.  With those rules, we can reuse
+     one multilib for certain different targets.  */
+  if (strlen(multilib_reuse) > 0)
+    p = concat (p, multilib_reuse, NULL);
+
   while (*p != '\0')
     {
-      /* Ignore newlines.  */
-      if (*p == '\n')
+      /* Ignore newlinesi and spaces.  */
+      if (*p == '\n' || *p == ' ')
 	{
 	  ++p;
 	  continue;
@@ -7487,8 +7502,8 @@ set_multilib_dir (void)
 	  if (*p == '\0')
 	    {
 	    invalid_select:
-	      fatal_error ("multilib select %qs is invalid",
-			   multilib_select);
+	      fatal_error ("multilib select %qs%qs is invalid",
+			   multilib_select, multilib_reuse);
 	    }
 	  ++p;
 	}
diff --git a/gcc/genmultilib b/gcc/genmultilib
index dc4751b..672af70 100644
--- a/gcc/genmultilib
+++ b/gcc/genmultilib
@@ -84,6 +84,9 @@
 # This argument can be used together with MULTILIB_EXCEPTIONS and will take
 # effect after the MULTILIB_EXCEPTIONS.
 
+# The optional ninth argument defines rules to reuse one multilib among
+# different targets.
+
 # The last option should be "yes" if multilibs are enabled.  If it is not
 # "yes", all GCC multilib dir names will be ".".
 
@@ -104,7 +107,7 @@
 #   genmultilib 'm64/m32 mno-app-regs|mcmodel=medany' '64 32 alt'
 #		'mcmodel?medany=mcmodel?medmid' 'm32/mno-app-regs* m32/mcmodel=*'
 #		'' 'm32/!m64/mno-app-regs m32/!m64/mcmodel=medany'
-#		'../lib64 ../lib32 alt' '' yes
+#		'../lib64 ../lib32 alt' '' '' yes
 # This produces:
 #   ". !m64 !m32 !mno-app-regs !mcmodel=medany;",
 #   "64:../lib64 m64 !m32 !mno-app-regs !mcmodel=medany;",
@@ -133,7 +136,8 @@ extra=$5
 exclusions=$6
 osdirnames=$7
 multilib_required=$8
-enable_multilib=$9
+multilib_reuse=$9
+enable_multilib=${10}
 
 echo "static const char *const multilib_raw[] = {"
 
@@ -341,12 +345,13 @@ done
 optout=`echo ${optout} | sed -e 's/^ //'`
 echo "\".${defaultosdirname} ${optout};\","
 
-# Work over the list of combinations.  We have to translate each one
-# to use the directory names rather than the option names, we have to
-# include the information in matches, and we have to generate the
-# correct list of options and negations.
-for combo in ${combinations}; do
-  # Use the directory names rather than the option names.
+function combo_to_dir()
+{
+  local combo
+  local dirout
+  local osdirout
+
+  combo=$1
   if [ -n "${todirnames}" ]; then
     dirout=`echo ${combo} | sed ${todirnames}`
   else
@@ -381,10 +386,17 @@ for combo in ${combinations}; do
       exit 1
     fi
   fi
+  echo "${dirout}"
+}
 
-  # Look through the options.  We must output each option that is
-  # present, and negate each option that is not present.
-  optout=
+# Function to look through the options and output each option that is present,
+# and negate each option that is not present.
+function options_output()
+{
+  local combo
+  local optout
+
+  combo=$1
   for set in ${options}; do
     setopts=`echo ${set} | sed -e 's_[/|]_ _g'`
     for opt in ${setopts}; do
@@ -396,6 +408,19 @@ for combo in ${combinations}; do
     done
   done
   optout=`echo ${optout} | sed -e 's/^ //'`
+  echo "${optout}"
+}
+
+# Work over the list of combinations.  We have to translate each one
+# to use the directory names rather than the option names, we have to
+# include the information in matches, and we have to generate the
+# correct list of options and negations.
+for combo in ${combinations}; do
+  # Use the directory names rather than the option names.
+  dirout=$(combo_to_dir ${combo})
+  # Look through the options.  We must output each option that is
+  # present, and negate each option that is not present.
+  optout=$(options_output ${combo})
 
   # Output the line with all appropriate matches.
   dirout="${dirout}" optout="${optout}" ./tmpmultilib2
@@ -405,6 +430,29 @@ done
 echo "NULL"
 echo "};"
 
+# Output rules used for multilib reuse.
+echo ""
+echo "static const char *const multilib_reuse_raw[] = {"
+for rrule in ${multilib_reuse}; do
+  # The left part of the rule are the options we used to build multilib.
+  # The right part of the rule are the options that can reuse this multilib.
+  combo=`echo ${rrule} | sed -e 's/=.*$//' -e 's/\./=/g'`
+  copts=`echo ${rrule} | sed -e 's/^.*=//' -e 's/\./=/g'`
+  # We only care rule that has concrete multilib.
+  if expr "${combinations} " : ".*/${combo}/.*" > /dev/null; then
+    combo="/${combo}/"
+    dirout=$(combo_to_dir ${combo})
+    copts="/${copts}/"
+    optout=$(options_output ${copts})
+    # Output the line with all appropriate matches.
+    dirout="${dirout}" optout="${optout}" ./tmpmultilib2
+  fi
+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 semicolon trailer.  Include all of the normal options as well.
 # Note, the format of the matches is reversed compared
-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: [RFC] New feature to reuse one multilib among different targets
  2012-11-08  1:37   ` Terry Guo
@ 2012-11-08 21:11     ` Joseph S. Myers
  2012-11-09  7:36       ` Terry Guo
  0 siblings, 1 reply; 13+ messages in thread
From: Joseph S. Myers @ 2012-11-08 21:11 UTC (permalink / raw)
  To: Terry Guo; +Cc: gcc-patches

On Thu, 8 Nov 2012, Terry Guo wrote:

> To convert such statements to data structure used by multilib_raw, I
> refactor codes in genmultilib into two functions combo_to_dir and

The "function" keyword for creating shell functions is not POSIX, and I 
don't know if we ensure that $SHELL is a shell supporting functions.  
(It's documented that CONFIG_SHELL may need to be set to a POSIX shell if 
/bin/sh isn't sufficient, but does that feed through to the value of SHELL 
used to run this script?)

> 2012-11-08  Terry Guo  <terry.guo@arm.com>
> 
> 	* genmultilib (combo_to_dir): New function.
> 	(options_output): New function.
> 	(MULTILIB_REUSE): New argument.
> 	* Makefile.in (s-mlib): Add a new argument MULTILIB_REUSE.
> 	* gcc.c (multilib_reuse): New spec.
> 	(set_multilib_dir): Use multilib_reuse.

Documentation changes need mentioning in ChangeLog entries.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: [RFC] New feature to reuse one multilib among different targets
  2012-11-08 21:11     ` Joseph S. Myers
@ 2012-11-09  7:36       ` Terry Guo
  2012-11-09 16:35         ` Joseph S. Myers
  0 siblings, 1 reply; 13+ messages in thread
From: Terry Guo @ 2012-11-09  7:36 UTC (permalink / raw)
  To: joseph; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1634 bytes --]

> -----Original Message-----
> From: Joseph Myers [mailto:joseph@codesourcery.com]
> Sent: Friday, November 09, 2012 5:10 AM
> To: Terry Guo
> Cc: gcc-patches@gcc.gnu.org
> Subject: RE: [RFC] New feature to reuse one multilib among different
> targets
> 
> On Thu, 8 Nov 2012, Terry Guo wrote:
> 
> > To convert such statements to data structure used by multilib_raw, I
> > refactor codes in genmultilib into two functions combo_to_dir and
> 
> The "function" keyword for creating shell functions is not POSIX, and I
> don't know if we ensure that $SHELL is a shell supporting functions.
> (It's documented that CONFIG_SHELL may need to be set to a POSIX shell
> if /bin/sh isn't sufficient, but does that feed through to the value of
> SHELL used to run this script?)
> 

You are right that we should make script POSIX compliant. This v3 patch
removed "function" and "local" which don't belong to POSIX standard. I also
verified that CONFIG_SHELL is passed to this script with value "/bin/sh".

Checked new genmultilib script with command "checkbashisms --posix
genmultilib" in Ubuntu. No warning and error messages reported.

[...]
> 
> Documentation changes need mentioning in ChangeLog entries.
> 

Added them in following ChangeLog.

BR,
Terry

2012-11-09  Terry Guo  <terry.guo@arm.com>

	* genmultilib (combo_to_dir): New function.
	(options_output): New function.
	(MULTILIB_REUSE): New argument.
	* Makefile.in (s-mlib): Add a new argument MULTILIB_REUSE.
	* gcc.c (multilib_reuse): New spec.
	(set_multilib_dir): Use multilib_reuse.
	* doc/fragments.texi: Mention MULTILIB_REUSE.

[-- Attachment #2: multilib-reuse-v3.patch --]
[-- Type: application/octet-stream, Size: 10213 bytes --]

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 24791a4..19b5f1c 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1808,10 +1808,11 @@ s-mlib: $(srcdir)/genmultilib Makefile
 	    "$(MULTILIB_EXCLUSIONS)" \
 	    "$(MULTILIB_OSDIRNAMES)" \
 	    "$(MULTILIB_REQUIRED)" \
+	    "$(MULTILIB_REUSE)" \
 	    "@enable_multilib@" \
 	    > tmp-mlib.h; \
 	else \
-	  $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' '' '' no\
+	  $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' '' '' '' no\
 	    > tmp-mlib.h; \
 	fi
 	$(SHELL) $(srcdir)/../move-if-change tmp-mlib.h multilib.h
diff --git a/gcc/doc/fragments.texi b/gcc/doc/fragments.texi
index f53df29..eeaefb0 100644
--- a/gcc/doc/fragments.texi
+++ b/gcc/doc/fragments.texi
@@ -144,6 +144,28 @@ The @code{MULTILIB_REQUIRED} can be used together with
 @code{MULTILIB_OPTIONS} will be filtered by @code{MULTILIB_EXCEPTIONS}
 and then by @code{MULTILIB_REQUIRED}.
 
+@findex MULTILIB_REUSE
+@item MULTILIB_REUSE
+Sometimes it is desirable to reuse one existing multilib among different
+targets.  Such kind of reuse can minimize the number of multilib variants.
+Also for some targets it is better to reuse an existing multilib than to
+fall back on default multilib when there is no corresponding multilib.  To
+achieve this, just set @code{MULTILIB_REUSE} to be the list of reuse rules.
+A typical reuse rule is comprised of two parts connected by equality sign.
+The left part of the rule are the options used to build multilib and the right
+part are the options representing target that will reuse this multilib.  The
+equality sign in both parts should be replaced with period.
+The @code{MULTILIB_REUSE} is different from @code{MULTILIB_MATCHES} in that it
+sets up relations between two option sets rather than two options.  Here is an
+example to demo how we reuse libraries built in Thumb mode for applications built
+in ARM mode:
+@smallexample
+@code{MULTILIB_REUSE} = mthumb/march.armv7-r=marm/march.armv7-r
+@end smallexample
+
+The @code{MULTILIB_REUSE} is a complementary way to select multilib.  Only when the
+original way fails it will work.
+
 @findex MULTILIB_EXTRA_OPTS
 @item MULTILIB_EXTRA_OPTS
 Sometimes it is desirable that when building multiple versions of
diff --git a/gcc/gcc.c b/gcc/gcc.c
index b80af44..f425734 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -830,6 +830,7 @@ static const char *multilib_select;
 static const char *multilib_matches;
 static const char *multilib_defaults;
 static const char *multilib_exclusions;
+static const char *multilib_reuse;
 
 /* Check whether a particular argument is a default argument.  */
 
@@ -1220,6 +1221,7 @@ static struct spec_list static_specs[] =
   INIT_STATIC_SPEC ("multilib_matches",		&multilib_matches),
   INIT_STATIC_SPEC ("multilib_exclusions",	&multilib_exclusions),
   INIT_STATIC_SPEC ("multilib_options",		&multilib_options),
+  INIT_STATIC_SPEC ("multilib_reuse",		&multilib_reuse),
   INIT_STATIC_SPEC ("linker",			&linker_name_spec),
   INIT_STATIC_SPEC ("linker_plugin_file",	&linker_plugin_file_spec),
   INIT_STATIC_SPEC ("lto_wrapper",		&lto_wrapper_spec),
@@ -6272,6 +6274,13 @@ main (int argc, char **argv)
     obstack_1grow (&multilib_obstack, 0);
     multilib_exclusions = XOBFINISH (&multilib_obstack, const char *);
 
+    q = multilib_reuse_raw;
+    while ((p = *q++) != (char *) 0)
+      obstack_grow (&multilib_obstack, p, strlen (p));
+
+    obstack_1grow (&multilib_obstack, 0);
+    multilib_reuse = XOBFINISH (&multilib_obstack, const char *);
+
     need_space = FALSE;
     for (i = 0; i < ARRAY_SIZE (multilib_defaults_raw); i++)
       {
@@ -7474,10 +7483,16 @@ set_multilib_dir (void)
 
   first = 1;
   p = multilib_select;
+
+  /* Append multilib reuse rules if any.  With those rules, we can reuse
+     one multilib for certain different targets.  */
+  if (strlen(multilib_reuse) > 0)
+    p = concat (p, multilib_reuse, NULL);
+
   while (*p != '\0')
     {
-      /* Ignore newlines.  */
-      if (*p == '\n')
+      /* Ignore newlinesi and spaces.  */
+      if (*p == '\n' || *p == ' ')
 	{
 	  ++p;
 	  continue;
@@ -7490,8 +7505,8 @@ set_multilib_dir (void)
 	  if (*p == '\0')
 	    {
 	    invalid_select:
-	      fatal_error ("multilib select %qs is invalid",
-			   multilib_select);
+	      fatal_error ("multilib select %qs%qs is invalid",
+			   multilib_select, multilib_reuse);
 	    }
 	  ++p;
 	}
diff --git a/gcc/genmultilib b/gcc/genmultilib
index dc4751b..cab7fa1 100644
--- a/gcc/genmultilib
+++ b/gcc/genmultilib
@@ -84,6 +84,9 @@
 # This argument can be used together with MULTILIB_EXCEPTIONS and will take
 # effect after the MULTILIB_EXCEPTIONS.
 
+# The optional ninth argument defines rules to reuse one multilib among
+# different targets.
+
 # The last option should be "yes" if multilibs are enabled.  If it is not
 # "yes", all GCC multilib dir names will be ".".
 
@@ -104,7 +107,7 @@
 #   genmultilib 'm64/m32 mno-app-regs|mcmodel=medany' '64 32 alt'
 #		'mcmodel?medany=mcmodel?medmid' 'm32/mno-app-regs* m32/mcmodel=*'
 #		'' 'm32/!m64/mno-app-regs m32/!m64/mcmodel=medany'
-#		'../lib64 ../lib32 alt' '' yes
+#		'../lib64 ../lib32 alt' '' '' yes
 # This produces:
 #   ". !m64 !m32 !mno-app-regs !mcmodel=medany;",
 #   "64:../lib64 m64 !m32 !mno-app-regs !mcmodel=medany;",
@@ -133,7 +136,8 @@ extra=$5
 exclusions=$6
 osdirnames=$7
 multilib_required=$8
-enable_multilib=$9
+multilib_reuse=$9
+enable_multilib=${10}
 
 echo "static const char *const multilib_raw[] = {"
 
@@ -341,35 +345,36 @@ done
 optout=`echo ${optout} | sed -e 's/^ //'`
 echo "\".${defaultosdirname} ${optout};\","
 
-# Work over the list of combinations.  We have to translate each one
-# to use the directory names rather than the option names, we have to
-# include the information in matches, and we have to generate the
-# correct list of options and negations.
-for combo in ${combinations}; do
-  # Use the directory names rather than the option names.
+combo_to_dir()
+{
+  mcombo=""
+  mdirout=""
+  mosdirout=""
+
+  mcombo=$1
   if [ -n "${todirnames}" ]; then
-    dirout=`echo ${combo} | sed ${todirnames}`
+    mdirout=`echo ${mcombo} | sed ${todirnames}`
   else
-    dirout=`echo ${combo} | sed -e 's/=/-/g'`
+    mdirout=`echo ${mcombo} | sed -e 's/=/-/g'`
   fi
   # Remove the leading and trailing slashes.
-  dirout=`echo ${dirout} | sed -e 's|^/||' -e 's|/$||g'`
+  mdirout=`echo ${mdirout} | sed -e 's|^/||' -e 's|/$||g'`
 
   # Use the OS directory names rather than the option names.
   if [ -n "${toosdirnames}" ]; then
-    osdirout=`echo ${combo} | sed ${toosdirnames}`
+    mosdirout=`echo ${mcombo} | sed ${toosdirnames}`
     # Remove the leading and trailing slashes.
-    osdirout=`echo ${osdirout} | sed -e 's|^/||' -e 's|/$||g'`
+    mosdirout=`echo ${mosdirout} | sed -e 's|^/||' -e 's|/$||g'`
     if [ "x${enable_multilib}" != xyes ]; then
-      dirout=".:${osdirout}"
+      mdirout=".:${mosdirout}"
       disable_multilib=yes
     else
-      case "${osdirout}" in
+      case "${mosdirout}" in
         !*)
-	  dirout=`echo ${osdirout} | sed 's/^!//'`
+	  mdirout=`echo ${mosdirout} | sed 's/^!//'`
 	  ;;
 	*)
-	  dirout="${dirout}:${osdirout}"
+	  mdirout="${mdirout}:${mosdirout}"
 	  ;;
       esac
     fi
@@ -381,21 +386,41 @@ for combo in ${combinations}; do
       exit 1
     fi
   fi
+  echo "${mdirout}"
+}
 
-  # Look through the options.  We must output each option that is
-  # present, and negate each option that is not present.
-  optout=
+# Function to look through the options and output each option that is present,
+# and negate each option that is not present.
+options_output()
+{
+  mcombo=""
+  moptout=""
+
+  mcombo=$1
   for set in ${options}; do
     setopts=`echo ${set} | sed -e 's_[/|]_ _g'`
     for opt in ${setopts}; do
-      if expr "${combo} " : ".*/${opt}/.*" > /dev/null; then
-	optout="${optout} ${opt}"
+      if expr "${mcombo} " : ".*/${opt}/.*" > /dev/null; then
+	moptout="${moptout} ${opt}"
       else
-	optout="${optout} !${opt}"
+	moptout="${moptout} !${opt}"
       fi
     done
   done
-  optout=`echo ${optout} | sed -e 's/^ //'`
+  moptout=`echo ${moptout} | sed -e 's/^ //'`
+  echo "${moptout}"
+}
+
+# Work over the list of combinations.  We have to translate each one
+# to use the directory names rather than the option names, we have to
+# include the information in matches, and we have to generate the
+# correct list of options and negations.
+for combo in ${combinations}; do
+  # Use the directory names rather than the option names.
+  dirout=$(combo_to_dir ${combo})
+  # Look through the options.  We must output each option that is
+  # present, and negate each option that is not present.
+  optout=$(options_output ${combo})
 
   # Output the line with all appropriate matches.
   dirout="${dirout}" optout="${optout}" ./tmpmultilib2
@@ -405,6 +430,29 @@ done
 echo "NULL"
 echo "};"
 
+# Output rules used for multilib reuse.
+echo ""
+echo "static const char *const multilib_reuse_raw[] = {"
+for rrule in ${multilib_reuse}; do
+  # The left part of the rule are the options we used to build multilib.
+  # The right part of the rule are the options that can reuse this multilib.
+  combo=`echo ${rrule} | sed -e 's/=.*$//' -e 's/\./=/g'`
+  copts=`echo ${rrule} | sed -e 's/^.*=//' -e 's/\./=/g'`
+  # We only care rule that has concrete multilib.
+  if expr "${combinations} " : ".*/${combo}/.*" > /dev/null; then
+    combo="/${combo}/"
+    dirout=$(combo_to_dir ${combo})
+    copts="/${copts}/"
+    optout=$(options_output ${copts})
+    # Output the line with all appropriate matches.
+    dirout="${dirout}" optout="${optout}" ./tmpmultilib2
+  fi
+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 semicolon trailer.  Include all of the normal options as well.
 # Note, the format of the matches is reversed compared

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: [RFC] New feature to reuse one multilib among different targets
  2012-11-09  7:36       ` Terry Guo
@ 2012-11-09 16:35         ` Joseph S. Myers
  2012-11-13  4:47           ` Terry Guo
  0 siblings, 1 reply; 13+ messages in thread
From: Joseph S. Myers @ 2012-11-09 16:35 UTC (permalink / raw)
  To: Terry Guo; +Cc: gcc-patches

On Fri, 9 Nov 2012, Terry Guo wrote:

> You are right that we should make script POSIX compliant. This v3 patch
> removed "function" and "local" which don't belong to POSIX standard. I also
> verified that CONFIG_SHELL is passed to this script with value "/bin/sh".

Suppose /bin/sh is not a POSIX shell but the user sets CONFIG_SHELL to 
something else (which is a POSIX shell).  Will SHELL in the makefile get 
set to the POSIX shell the user specified as CONFIG_SHELL?  That's what's 
needed to be able to use POSIX shell features in this script.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: [RFC] New feature to reuse one multilib among different targets
  2012-11-09 16:35         ` Joseph S. Myers
@ 2012-11-13  4:47           ` Terry Guo
  2012-11-23  9:12             ` Ping: " Terry Guo
  2012-12-06 18:04             ` Joseph S. Myers
  0 siblings, 2 replies; 13+ messages in thread
From: Terry Guo @ 2012-11-13  4:47 UTC (permalink / raw)
  To: joseph; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1490 bytes --]

> -----Original Message-----
> From: Joseph Myers [mailto:joseph@codesourcery.com]
> Sent: Saturday, November 10, 2012 12:35 AM
> To: Terry Guo
> Cc: gcc-patches@gcc.gnu.org
> Subject: RE: [RFC] New feature to reuse one multilib among different
> targets
> 
> On Fri, 9 Nov 2012, Terry Guo wrote:
> 
> > You are right that we should make script POSIX compliant. This v3
> patch
> > removed "function" and "local" which don't belong to POSIX standard.
> I also
> > verified that CONFIG_SHELL is passed to this script with value
> "/bin/sh".
> 
> Suppose /bin/sh is not a POSIX shell but the user sets CONFIG_SHELL to
> something else (which is a POSIX shell).  Will SHELL in the makefile
> get
> set to the POSIX shell the user specified as CONFIG_SHELL?  That's
> what's
> needed to be able to use POSIX shell features in this script.
> 

The attached patch is updated to use sub-script rather than the function to
reuse code. Is it ok to avoid the issue you just mentioned?

BR,
Terry

2012-11-13  Terry Guo  <terry.guo@arm.com>

	* genmultilib (tmpmultilib3): New refactored sub-script
	to convert the option combination into folder name.
	(tmpmultilib4): New refactored sub-script to output the
	options in a option combination.
	(MULTILIB_REUSE): New argument.
	* Makefile.in (s-mlib): Add a new argument MULTILIB_REUSE.
	* gcc.c (multilib_reuse): New spec.
	(set_multilib_dir): Use multilib_reuse.
	* doc/fragments.texi: Mention MULTILIB_REUSE.

[-- Attachment #2: multilib-reuse-v4.patch --]
[-- Type: application/octet-stream, Size: 10839 bytes --]

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 83a424e..982cf20 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1809,10 +1809,11 @@ s-mlib: $(srcdir)/genmultilib Makefile
 	    "$(MULTILIB_EXCLUSIONS)" \
 	    "$(MULTILIB_OSDIRNAMES)" \
 	    "$(MULTILIB_REQUIRED)" \
+	    "$(MULTILIB_REUSE)" \
 	    "@enable_multilib@" \
 	    > tmp-mlib.h; \
 	else \
-	  $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' '' '' no\
+	  $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' '' '' '' no\
 	    > tmp-mlib.h; \
 	fi
 	$(SHELL) $(srcdir)/../move-if-change tmp-mlib.h multilib.h
diff --git a/gcc/doc/fragments.texi b/gcc/doc/fragments.texi
index f53df29..6935b15 100644
--- a/gcc/doc/fragments.texi
+++ b/gcc/doc/fragments.texi
@@ -144,6 +144,28 @@ The @code{MULTILIB_REQUIRED} can be used together with
 @code{MULTILIB_OPTIONS} will be filtered by @code{MULTILIB_EXCEPTIONS}
 and then by @code{MULTILIB_REQUIRED}.
 
+@findex MULTILIB_REUSE
+@item MULTILIB_REUSE
+Sometimes it is desirable to reuse one existing multilib among different
+targets.  Such kind of reuse can minimize the number of multilib variants.
+Also for some targets it is better to reuse an existing multilib than to
+fall back on default multilib when there is no corresponding multilib.  To
+achieve this, just set @code{MULTILIB_REUSE} to the list of reuse rules.
+A typical reuse rule is comprised of two parts connected by equality sign.
+The left part of the rule are the options used to build multilib and the right
+part are the options representing target that will reuse this multilib.  The
+equality sign in both parts should be replaced with period.
+The @code{MULTILIB_REUSE} is different from @code{MULTILIB_MATCHES} in that it
+sets up relations between two option sets rather than two options.  Here is an
+example to demo how we reuse libraries built in Thumb mode for applications built
+in ARM mode:
+@smallexample
+@code{MULTILIB_REUSE} = mthumb/march.armv7-r=marm/march.armv7-r
+@end smallexample
+
+The @code{MULTILIB_REUSE} is a complementary way to select multilib.  Only when the
+original way fails it will work.
+
 @findex MULTILIB_EXTRA_OPTS
 @item MULTILIB_EXTRA_OPTS
 Sometimes it is desirable that when building multiple versions of
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 2102771..64aaedd 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -831,6 +831,7 @@ static const char *multilib_select;
 static const char *multilib_matches;
 static const char *multilib_defaults;
 static const char *multilib_exclusions;
+static const char *multilib_reuse;
 
 /* Check whether a particular argument is a default argument.  */
 
@@ -1221,6 +1222,7 @@ static struct spec_list static_specs[] =
   INIT_STATIC_SPEC ("multilib_matches",		&multilib_matches),
   INIT_STATIC_SPEC ("multilib_exclusions",	&multilib_exclusions),
   INIT_STATIC_SPEC ("multilib_options",		&multilib_options),
+  INIT_STATIC_SPEC ("multilib_reuse",		&multilib_reuse),
   INIT_STATIC_SPEC ("linker",			&linker_name_spec),
   INIT_STATIC_SPEC ("linker_plugin_file",	&linker_plugin_file_spec),
   INIT_STATIC_SPEC ("lto_wrapper",		&lto_wrapper_spec),
@@ -6273,6 +6275,13 @@ main (int argc, char **argv)
     obstack_1grow (&multilib_obstack, 0);
     multilib_exclusions = XOBFINISH (&multilib_obstack, const char *);
 
+    q = multilib_reuse_raw;
+    while ((p = *q++) != (char *) 0)
+      obstack_grow (&multilib_obstack, p, strlen (p));
+
+    obstack_1grow (&multilib_obstack, 0);
+    multilib_reuse = XOBFINISH (&multilib_obstack, const char *);
+
     need_space = FALSE;
     for (i = 0; i < ARRAY_SIZE (multilib_defaults_raw); i++)
       {
@@ -7475,10 +7484,16 @@ set_multilib_dir (void)
 
   first = 1;
   p = multilib_select;
+
+  /* Append multilib reuse rules if any.  With those rules, we can reuse
+     one multilib for certain different targets.  */
+  if (strlen(multilib_reuse) > 0)
+    p = concat (p, multilib_reuse, NULL);
+
   while (*p != '\0')
     {
-      /* Ignore newlines.  */
-      if (*p == '\n')
+      /* Ignore newlinesi and spaces.  */
+      if (*p == '\n' || *p == ' ')
 	{
 	  ++p;
 	  continue;
@@ -7491,8 +7506,8 @@ set_multilib_dir (void)
 	  if (*p == '\0')
 	    {
 	    invalid_select:
-	      fatal_error ("multilib select %qs is invalid",
-			   multilib_select);
+	      fatal_error ("multilib select %qs%qs is invalid",
+			   multilib_select, multilib_reuse);
 	    }
 	  ++p;
 	}
diff --git a/gcc/genmultilib b/gcc/genmultilib
index dc4751b..ac89cec 100644
--- a/gcc/genmultilib
+++ b/gcc/genmultilib
@@ -84,6 +84,9 @@
 # This argument can be used together with MULTILIB_EXCEPTIONS and will take
 # effect after the MULTILIB_EXCEPTIONS.
 
+# The optional ninth argument defines rules to reuse one multilib among
+# different targets.
+
 # The last option should be "yes" if multilibs are enabled.  If it is not
 # "yes", all GCC multilib dir names will be ".".
 
@@ -104,7 +107,7 @@
 #   genmultilib 'm64/m32 mno-app-regs|mcmodel=medany' '64 32 alt'
 #		'mcmodel?medany=mcmodel?medmid' 'm32/mno-app-regs* m32/mcmodel=*'
 #		'' 'm32/!m64/mno-app-regs m32/!m64/mcmodel=medany'
-#		'../lib64 ../lib32 alt' '' yes
+#		'../lib64 ../lib32 alt' '' '' yes
 # This produces:
 #   ". !m64 !m32 !mno-app-regs !mcmodel=medany;",
 #   "64:../lib64 m64 !m32 !mno-app-regs !mcmodel=medany;",
@@ -133,7 +136,8 @@ extra=$5
 exclusions=$6
 osdirnames=$7
 multilib_required=$8
-enable_multilib=$9
+multilib_reuse=$9
+enable_multilib=${10}
 
 echo "static const char *const multilib_raw[] = {"
 
@@ -341,62 +345,84 @@ done
 optout=`echo ${optout} | sed -e 's/^ //'`
 echo "\".${defaultosdirname} ${optout};\","
 
+rm -rf tmpmultilib3
+cat >tmpmultilib3 <<\EOF
+#!/bin/sh
+combo=$1
+todirnames=$2
+toosdirnames=$3
+enable_multilib=$4
+
+if [ -n "${todirnames}" ]; then
+  dirout=`echo ${combo} | sed ${todirnames}`
+else
+  dirout=`echo ${combo} | sed -e 's/=/-/g'`
+fi
+# Remove the leading and trailing slashes.
+dirout=`echo ${dirout} | sed -e 's|^/||' -e 's|/$||g'`
+
+# Use the OS directory names rather than the option names.
+if [ -n "${toosdirnames}" ]; then
+  osdirout=`echo ${combo} | sed ${toosdirnames}`
+  # Remove the leading and trailing slashes.
+  osdirout=`echo ${osdirout} | sed -e 's|^/||' -e 's|/$||g'`
+  if [ "x${enable_multilib}" != xyes ]; then
+    dirout=".:${osdirout}"
+    disable_multilib=yes
+  else
+    case "${osdirout}" in
+      !*)
+	dirout=`echo ${osdirout} | sed 's/^!//'`
+	;;
+      *)
+	dirout="${dirout}:${osdirout}"
+	;;
+    esac
+  fi
+else
+  if [ "x${enable_multilib}" != xyes ]; then
+    # genmultilib with --disable-multilib should be
+    # called with '' '' '' '' '' '' '' no
+    # if MULTILIB_OSDIRNAMES is empty.
+    exit 1
+  fi
+fi
+echo "${dirout}"
+EOF
+chmod +x tmpmultilib3
+
+# Script to look through the options and output each option that is present,
+# and negate each option that is not present.
+rm -rf tmpmultilib4
+cat > tmpmultilib4 <<\EOF
+#!/bin/sh
+combo=$1
+options=$2
+for set in ${options}; do
+  setopts=`echo ${set} | sed -e 's_[/|]_ _g'`
+  for opt in ${setopts}; do
+    if expr "${combo} " : ".*/${opt}/.*" > /dev/null; then
+      optout="${optout} ${opt}"
+    else
+      optout="${optout} !${opt}"
+    fi
+  done
+done
+optout=`echo ${optout} | sed -e 's/^ //'`
+echo "${optout}"
+EOF
+chmod +x tmpmultilib4
+
 # Work over the list of combinations.  We have to translate each one
 # to use the directory names rather than the option names, we have to
 # include the information in matches, and we have to generate the
 # correct list of options and negations.
 for combo in ${combinations}; do
   # Use the directory names rather than the option names.
-  if [ -n "${todirnames}" ]; then
-    dirout=`echo ${combo} | sed ${todirnames}`
-  else
-    dirout=`echo ${combo} | sed -e 's/=/-/g'`
-  fi
-  # Remove the leading and trailing slashes.
-  dirout=`echo ${dirout} | sed -e 's|^/||' -e 's|/$||g'`
-
-  # Use the OS directory names rather than the option names.
-  if [ -n "${toosdirnames}" ]; then
-    osdirout=`echo ${combo} | sed ${toosdirnames}`
-    # Remove the leading and trailing slashes.
-    osdirout=`echo ${osdirout} | sed -e 's|^/||' -e 's|/$||g'`
-    if [ "x${enable_multilib}" != xyes ]; then
-      dirout=".:${osdirout}"
-      disable_multilib=yes
-    else
-      case "${osdirout}" in
-        !*)
-	  dirout=`echo ${osdirout} | sed 's/^!//'`
-	  ;;
-	*)
-	  dirout="${dirout}:${osdirout}"
-	  ;;
-      esac
-    fi
-  else
-    if [ "x${enable_multilib}" != xyes ]; then
-      # genmultilib with --disable-multilib should be
-      # called with '' '' '' '' '' '' '' no
-      # if MULTILIB_OSDIRNAMES is empty.
-      exit 1
-    fi
-  fi
-
+  dirout=`./tmpmultilib3 "${combo}" "${todirnames}" "${toosdirnames}" "${enable_multilib}"`
   # Look through the options.  We must output each option that is
   # present, and negate each option that is not present.
-  optout=
-  for set in ${options}; do
-    setopts=`echo ${set} | sed -e 's_[/|]_ _g'`
-    for opt in ${setopts}; do
-      if expr "${combo} " : ".*/${opt}/.*" > /dev/null; then
-	optout="${optout} ${opt}"
-      else
-	optout="${optout} !${opt}"
-      fi
-    done
-  done
-  optout=`echo ${optout} | sed -e 's/^ //'`
-
+  optout=`./tmpmultilib4 "${combo}" "${options}"`
   # Output the line with all appropriate matches.
   dirout="${dirout}" optout="${optout}" ./tmpmultilib2
 done
@@ -405,6 +431,29 @@ done
 echo "NULL"
 echo "};"
 
+# Output rules used for multilib reuse.
+echo ""
+echo "static const char *const multilib_reuse_raw[] = {"
+for rrule in ${multilib_reuse}; do
+  # The left part of the rule are the options we used to build multilib.
+  # The right part of the rule are the options that can reuse this multilib.
+  combo=`echo ${rrule} | sed -e 's/=.*$//' -e 's/\./=/g'`
+  copts=`echo ${rrule} | sed -e 's/^.*=//' -e 's/\./=/g'`
+  # We only care rule that has concrete multilib.
+  if expr "${combinations} " : ".*/${combo}/.*" > /dev/null; then
+    combo="/${combo}/"
+    dirout=`./tmpmultilib3 "${combo}" "${todirnames}" "${toosdirnames}" "${enable_multilib}"`
+    copts="/${copts}/"
+    optout=`./tmpmultilib4 "${copts}" "${options}"`
+    # Output the line with all appropriate matches.
+    dirout="${dirout}" optout="${optout}" ./tmpmultilib2
+  fi
+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 semicolon trailer.  Include all of the normal options as well.
 # Note, the format of the matches is reversed compared

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Ping: RE: [RFC] New feature to reuse one multilib among different targets
  2012-11-13  4:47           ` Terry Guo
@ 2012-11-23  9:12             ` Terry Guo
  2012-12-04  2:36               ` Ping-2: " Terry Guo
  2012-12-06 18:04             ` Joseph S. Myers
  1 sibling, 1 reply; 13+ messages in thread
From: Terry Guo @ 2012-11-23  9:12 UTC (permalink / raw)
  To: joseph; +Cc: gcc-patches

Hi Joseph,

Can you please help to review this patch and share your thoughts on this
feature? Thanks.

BR,
Terry

> -----Original Message-----
> From: gcc-patches-owner@gcc.gnu.org [mailto:gcc-patches-
> owner@gcc.gnu.org] On Behalf Of Terry Guo
> Sent: Tuesday, November 13, 2012 12:47 PM
> To: joseph@codesourcery.com
> Cc: gcc-patches@gcc.gnu.org
> Subject: RE: [RFC] New feature to reuse one multilib among different
> targets
> 
> > -----Original Message-----
> > From: Joseph Myers [mailto:joseph@codesourcery.com]
> > Sent: Saturday, November 10, 2012 12:35 AM
> > To: Terry Guo
> > Cc: gcc-patches@gcc.gnu.org
> > Subject: RE: [RFC] New feature to reuse one multilib among different
> > targets
> >
> > On Fri, 9 Nov 2012, Terry Guo wrote:
> >
> > > You are right that we should make script POSIX compliant. This v3
> > patch
> > > removed "function" and "local" which don't belong to POSIX standard.
> > I also
> > > verified that CONFIG_SHELL is passed to this script with value
> > "/bin/sh".
> >
> > Suppose /bin/sh is not a POSIX shell but the user sets CONFIG_SHELL
> to
> > something else (which is a POSIX shell).  Will SHELL in the makefile
> > get set to the POSIX shell the user specified as CONFIG_SHELL?
> That's
> > what's needed to be able to use POSIX shell features in this script.
> >
> 
> The attached patch is updated to use sub-script rather than the
> function to
> reuse code. Is it ok to avoid the issue you just mentioned?
> 
> BR,
> Terry
> 
> 2012-11-13  Terry Guo  <terry.guo@arm.com>
> 
> 	* genmultilib (tmpmultilib3): New refactored sub-script
> 	to convert the option combination into folder name.
> 	(tmpmultilib4): New refactored sub-script to output the
> 	options in a option combination.
> 	(MULTILIB_REUSE): New argument.
> 	* Makefile.in (s-mlib): Add a new argument MULTILIB_REUSE.
> 	* gcc.c (multilib_reuse): New spec.
> 	(set_multilib_dir): Use multilib_reuse.
> 	* doc/fragments.texi: Mention MULTILIB_REUSE.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Ping-2: RE: [RFC] New feature to reuse one multilib among different targets
  2012-11-23  9:12             ` Ping: " Terry Guo
@ 2012-12-04  2:36               ` Terry Guo
  0 siblings, 0 replies; 13+ messages in thread
From: Terry Guo @ 2012-12-04  2:36 UTC (permalink / raw)
  To: joseph; +Cc: gcc-patches

Hi Joseph,

Can you please review this patch? If I missed something, please point out.
Thanks.

BR,
Terry

> -----Original Message-----
> From: gcc-patches-owner@gcc.gnu.org [mailto:gcc-patches-
> owner@gcc.gnu.org] On Behalf Of Terry Guo
> Sent: Friday, November 23, 2012 5:12 PM
> To: joseph@codesourcery.com
> Cc: gcc-patches@gcc.gnu.org
> Subject: Ping: RE: [RFC] New feature to reuse one multilib among
> different targets
> 
> Hi Joseph,
> 
> Can you please help to review this patch and share your thoughts on
> this
> feature? Thanks.
> 
> BR,
> Terry
> 
> > -----Original Message-----
> > From: gcc-patches-owner@gcc.gnu.org [mailto:gcc-patches-
> > owner@gcc.gnu.org] On Behalf Of Terry Guo
> > Sent: Tuesday, November 13, 2012 12:47 PM
> > To: joseph@codesourcery.com
> > Cc: gcc-patches@gcc.gnu.org
> > Subject: RE: [RFC] New feature to reuse one multilib among different
> > targets
> >
> > > -----Original Message-----
> > > From: Joseph Myers [mailto:joseph@codesourcery.com]
> > > Sent: Saturday, November 10, 2012 12:35 AM
> > > To: Terry Guo
> > > Cc: gcc-patches@gcc.gnu.org
> > > Subject: RE: [RFC] New feature to reuse one multilib among
> different
> > > targets
> > >
> > > On Fri, 9 Nov 2012, Terry Guo wrote:
> > >
> > > > You are right that we should make script POSIX compliant. This v3
> > > patch
> > > > removed "function" and "local" which don't belong to POSIX
> standard.
> > > I also
> > > > verified that CONFIG_SHELL is passed to this script with value
> > > "/bin/sh".
> > >
> > > Suppose /bin/sh is not a POSIX shell but the user sets CONFIG_SHELL
> > to
> > > something else (which is a POSIX shell).  Will SHELL in the
> makefile
> > > get set to the POSIX shell the user specified as CONFIG_SHELL?
> > That's
> > > what's needed to be able to use POSIX shell features in this script.
> > >
> >
> > The attached patch is updated to use sub-script rather than the
> > function to
> > reuse code. Is it ok to avoid the issue you just mentioned?
> >
> > BR,
> > Terry
> >
> > 2012-11-13  Terry Guo  <terry.guo@arm.com>
> >
> > 	* genmultilib (tmpmultilib3): New refactored sub-script
> > 	to convert the option combination into folder name.
> > 	(tmpmultilib4): New refactored sub-script to output the
> > 	options in a option combination.
> > 	(MULTILIB_REUSE): New argument.
> > 	* Makefile.in (s-mlib): Add a new argument MULTILIB_REUSE.
> > 	* gcc.c (multilib_reuse): New spec.
> > 	(set_multilib_dir): Use multilib_reuse.
> > 	* doc/fragments.texi: Mention MULTILIB_REUSE.
> 
> 



^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: [RFC] New feature to reuse one multilib among different targets
  2012-11-13  4:47           ` Terry Guo
  2012-11-23  9:12             ` Ping: " Terry Guo
@ 2012-12-06 18:04             ` Joseph S. Myers
  2012-12-07 13:24               ` Terry Guo
  1 sibling, 1 reply; 13+ messages in thread
From: Joseph S. Myers @ 2012-12-06 18:04 UTC (permalink / raw)
  To: Terry Guo; +Cc: gcc-patches

On Tue, 13 Nov 2012, Terry Guo wrote:

> +@findex MULTILIB_REUSE
> +@item MULTILIB_REUSE
> +Sometimes it is desirable to reuse one existing multilib among different
> +targets.  Such kind of reuse can minimize the number of multilib variants.

I don't think "among different targets" is the right wording here.  "for 
different sets of options"?

> +A typical reuse rule is comprised of two parts connected by equality sign.

Not just a typical reuse rule, but *any* reuse rule, as I understand it.

> +The left part of the rule are the options used to build multilib and the right
> +part are the options representing target that will reuse this multilib.  The
> +equality sign in both parts should be replaced with period.

Is the order of the options significant, on either or both sides?  Can the 
options on the right hand side be options that aren't used to build any 
multilibs?  I think the documentation should answer that sort of question.

> @@ -7475,10 +7484,16 @@ set_multilib_dir (void)
>  
>    first = 1;
>    p = multilib_select;
> +
> +  /* Append multilib reuse rules if any.  With those rules, we can reuse
> +     one multilib for certain different targets.  */
> +  if (strlen(multilib_reuse) > 0)

Missing space before '('.

> -      /* Ignore newlines.  */
> -      if (*p == '\n')
> +      /* Ignore newlinesi and spaces.  */

Typo "newlinesi".  And why the change to ignore spaces as well - what's 
different about this new feature to require that?

> @@ -7491,8 +7506,8 @@ set_multilib_dir (void)
>  	  if (*p == '\0')
>  	    {
>  	    invalid_select:
> -	      fatal_error ("multilib select %qs is invalid",
> -			   multilib_select);
> +	      fatal_error ("multilib select %qs%qs is invalid",
> +			   multilib_select, multilib_reuse);

Printing two quoted strings with no space between the closing quote of one 
and the opening quote of the other certainly doesn't seem right.  (Really 
this whole error message seems pretty bad - it won't make sense to users - 
but that's a pre-existing condition.)

> +rm -rf tmpmultilib3
> +cat >tmpmultilib3 <<\EOF

As I understand it, this is a refactoring of existing code.  The patch 
might be easier to review if the bits that just refactored existing code 
into sub-scripts (without any changes to that code) were sent as a 
separate self-contained patch, and then the new feature patch was sent as 
a patch applying on top of those.

> +  # We only care rule that has concrete multilib.

"care about", I think, but this sentence still doesn't really make sense 
to me.  What are the cases that aren't being cared about here, and why are 
they valid inputs?  Surely, given a proper MULTILIB_REUSE setting, every 
rule in that setting should do something meaningful and rules that don't 
should result in errors?

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: [RFC] New feature to reuse one multilib among different targets
  2012-12-06 18:04             ` Joseph S. Myers
@ 2012-12-07 13:24               ` Terry Guo
  2013-01-07 16:13                 ` Joseph S. Myers
  0 siblings, 1 reply; 13+ messages in thread
From: Terry Guo @ 2012-12-07 13:24 UTC (permalink / raw)
  To: joseph; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 4661 bytes --]



> -----Original Message-----
> From: Joseph Myers [mailto:joseph@codesourcery.com]
> Sent: Friday, December 07, 2012 2:04 AM
> To: Terry Guo
> Cc: gcc-patches@gcc.gnu.org
> Subject: RE: [RFC] New feature to reuse one multilib among different
> targets
> 
> On Tue, 13 Nov 2012, Terry Guo wrote:
> 
> > +@findex MULTILIB_REUSE
> > +@item MULTILIB_REUSE
> > +Sometimes it is desirable to reuse one existing multilib among
> different
> > +targets.  Such kind of reuse can minimize the number of multilib
> variants.
> 
> I don't think "among different targets" is the right wording here.
> "for
> different sets of options"?
> 

Updated with your comments.

> > +A typical reuse rule is comprised of two parts connected by equality
> sign.
> 
> Not just a typical reuse rule, but *any* reuse rule, as I understand it.
> 

You are right. Removed the word "typical".

> > +The left part of the rule are the options used to build multilib and
> the right
> > +part are the options representing target that will reuse this
> multilib.  The
> > +equality sign in both parts should be replaced with period.
> 
> Is the order of the options significant, on either or both sides?  Can
> the
> options on the right hand side be options that aren't used to build any
> multilibs?  I think the documentation should answer that sort of
> question.
> 

Yes, the option order in left part matters. More explanations are added as
in patch.

> > @@ -7475,10 +7484,16 @@ set_multilib_dir (void)
> >
> >    first = 1;
> >    p = multilib_select;
> > +
> > +  /* Append multilib reuse rules if any.  With those rules, we can
> reuse
> > +     one multilib for certain different targets.  */
> > +  if (strlen(multilib_reuse) > 0)
> 
> Missing space before '('.
> 

Added the missing space.

> > -      /* Ignore newlines.  */
> > -      if (*p == '\n')
> > +      /* Ignore newlinesi and spaces.  */
> 
> Typo "newlinesi".  And why the change to ignore spaces as well - what's
> different about this new feature to require that?
> 

Typo is corrected. I once wanted to enable user to change multilib spec in
gcc driver on the fly by defining own spec file with content:

*multilib:
OWN RULES

or

*multilib:
+ OWN RULES

For the latter case, an extra space will be involved and break the parse of
multilib spec. So I ignore space here.

But as your said we had better not touch those internal data structure, I
give up this idea now.

> > @@ -7491,8 +7506,8 @@ set_multilib_dir (void)
> >  	  if (*p == '\0')
> >  	    {
> >  	    invalid_select:
> > -	      fatal_error ("multilib select %qs is invalid",
> > -			   multilib_select);
> > +	      fatal_error ("multilib select %qs%qs is invalid",
> > +			   multilib_select, multilib_reuse);
> 
> Printing two quoted strings with no space between the closing quote of
> one
> and the opening quote of the other certainly doesn't seem right.
> (Really
> this whole error message seems pretty bad - it won't make sense to
> users -
> but that's a pre-existing condition.)
> 

An extra space is inserted.

> > +rm -rf tmpmultilib3
> > +cat >tmpmultilib3 <<\EOF
> 
> As I understand it, this is a refactoring of existing code.  The patch
> might be easier to review if the bits that just refactored existing
> code
> into sub-scripts (without any changes to that code) were sent as a
> separate self-contained patch, and then the new feature patch was sent
> as
> a patch applying on top of those.
> 

Your understanding is correct. Now I put code refactor part into patch 00.
Patch 01 is supposed to be applied on top of it.

> > +  # We only care rule that has concrete multilib.
> 
> "care about", I think, but this sentence still doesn't really make
> sense
> to me.  What are the cases that aren't being cared about here, and why
> are
> they valid inputs?  Surely, given a proper MULTILIB_REUSE setting,
> every
> rule in that setting should do something meaningful and rules that
> don't
> should result in errors?
> 

Now an error will be generated once the rule tries to reuse nonexistent
multilib.

Thank you again, Joseph.

BR,
Terry

2012-12-07  Terry Guo  <terry.guo@arm.com>

        * gcc/Makefile.in (s-mlib): New argument MULTILIB_REUSE.
        * gcc/doc/fragments.texi: Document MULTILIB_REUSE.
        * gcc/gcc.c (multilib_reuse): New internal spec.
        (set_multilib_dir): Also search multilib from multilib_reuse.
        * gcc/genmultilib (tmpmultilib3): Refactor code.
        (tmpmultilib4): Ditto.
        (multilib_reuse): New multilib argument.
	

[-- Attachment #2: 00-multilib-reuse-v5.patch --]
[-- Type: application/octet-stream, Size: 4449 bytes --]

diff --git a/gcc/genmultilib b/gcc/genmultilib
index 09b6346..6ed1855 100644
--- a/gcc/genmultilib
+++ b/gcc/genmultilib
@@ -350,61 +350,94 @@ done
 optout=`echo ${optout} | sed -e 's/^ //'`
 echo "\".${defaultosdirname} ${optout};\","
 
+# This part of code convert an option combination to
+# its corresponding directory names.
+# The directory names will be deduced from MULTILIB_DIRNAMES,
+# MULTILIB_OSDIRNAMES or the option combination itself.
+rm -rf tmpmultilib3
+cat >tmpmultilib3 <<\EOF
+#!/bin/sh
+
+dirout=
+combo=$1
+todirnames=$2
+toosdirnames=$3
+enable_multilib=$4
+
+if [ -n "${todirnames}" ]; then
+  dirout=`echo ${combo} | sed ${todirnames}`
+else
+  dirout=`echo ${combo} | sed -e 's/=/-/g'`
+fi
+# Remove the leading and trailing slashes.
+dirout=`echo ${dirout} | sed -e 's|^/||' -e 's|/*:/*|:|' -e 's|/$||g'`
+
+# Use the OS directory names rather than the option names.
+if [ -n "${toosdirnames}" ]; then
+  osdirout=`echo ${combo} | sed ${toosdirnames}`
+  # Remove the leading and trailing slashes.
+  osdirout=`echo ${osdirout} | sed -e 's|^/||' -e 's|/*:/*|:|' -e 's|/$||g'`
+  if [ "x${enable_multilib}" != xyes ]; then
+    dirout=".:${osdirout}"
+    disable_multilib=yes
+  else
+    case "${osdirout}" in
+      !*)
+	dirout=`echo ${osdirout} | sed 's/^!//'`
+	;;
+       *)
+	dirout="${dirout}:${osdirout}"
+	;;
+    esac
+  fi
+else
+  if [ "x${enable_multilib}" != xyes ]; then
+    # genmultilib with --disable-multilib should be
+    # called with '' '' '' '' '' '' '' no
+    # if MULTILIB_OSDIRNAMES is empty.
+    exit 1
+  fi
+fi
+echo "${dirout}"
+EOF
+chmod +x tmpmultilib3
+
+# Script to look through the options and output each option that is present,
+# and negate each option that is not present.
+rm -rf tmpmultilib4
+cat > tmpmultilib4 <<\EOF
+#!/bin/sh
+
+optout=
+combo=$1
+options=$2
+
+for set in ${options}; do
+  setopts=`echo ${set} | sed -e 's_[/|]_ _g'`
+  for opt in ${setopts}; do
+    if expr "${combo} " : ".*/${opt}/.*" > /dev/null; then
+      optout="${optout} ${opt}"
+    else
+      optout="${optout} !${opt}"
+    fi
+  done
+done
+optout=`echo ${optout} | sed -e 's/^ //'`
+echo "${optout}"
+EOF
+chmod +x tmpmultilib4
+
 # Work over the list of combinations.  We have to translate each one
 # to use the directory names rather than the option names, we have to
 # include the information in matches, and we have to generate the
 # correct list of options and negations.
 for combo in ${combinations}; do
   # Use the directory names rather than the option names.
-  if [ -n "${todirnames}" ]; then
-    dirout=`echo ${combo} | sed ${todirnames}`
-  else
-    dirout=`echo ${combo} | sed -e 's/=/-/g'`
-  fi
-  # Remove the leading and trailing slashes.
-  dirout=`echo ${dirout} | sed -e 's|^/||' -e 's|/*:/*|:|' -e 's|/$||g'`
-
-  # Use the OS directory names rather than the option names.
-  if [ -n "${toosdirnames}" ]; then
-    osdirout=`echo ${combo} | sed ${toosdirnames}`
-    # Remove the leading and trailing slashes.
-    osdirout=`echo ${osdirout} | sed -e 's|^/||' -e 's|/*:/*|:|' -e 's|/$||g'`
-    if [ "x${enable_multilib}" != xyes ]; then
-      dirout=".:${osdirout}"
-      disable_multilib=yes
-    else
-      case "${osdirout}" in
-        !*)
-	  dirout=`echo ${osdirout} | sed 's/^!//'`
-	  ;;
-	*)
-	  dirout="${dirout}:${osdirout}"
-	  ;;
-      esac
-    fi
-  else
-    if [ "x${enable_multilib}" != xyes ]; then
-      # genmultilib with --disable-multilib should be
-      # called with '' '' '' '' '' '' '' no
-      # if MULTILIB_OSDIRNAMES is empty.
-      exit 1
-    fi
-  fi
+  dirout=`./tmpmultilib3 "${combo}" "${todirnames}" "${toosdirnames}" "${enable_multilib}"`
 
   # Look through the options.  We must output each option that is
   # present, and negate each option that is not present.
-  optout=
-  for set in ${options}; do
-    setopts=`echo ${set} | sed -e 's_[/|]_ _g'`
-    for opt in ${setopts}; do
-      if expr "${combo} " : ".*/${opt}/.*" > /dev/null; then
-	optout="${optout} ${opt}"
-      else
-	optout="${optout} !${opt}"
-      fi
-    done
-  done
-  optout=`echo ${optout} | sed -e 's/^ //'`
+  optout=`./tmpmultilib4 "${combo}" "${options}"`
 
   # Output the line with all appropriate matches.
   dirout="${dirout}" optout="${optout}" ./tmpmultilib2
-- 
1.7.9.5


[-- Attachment #3: 01-multilib-reuse-v5.patch --]
[-- Type: application/octet-stream, Size: 7481 bytes --]

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 9efc2d3..2b9230d 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1826,10 +1826,12 @@ s-mlib: $(srcdir)/genmultilib Makefile
 	    "$(MULTILIB_OSDIRNAMES)" \
 	    "$(MULTILIB_REQUIRED)" \
 	    "$(MULTIARCH_DIRNAME)" \
+	    "$(MULTILIB_REUSE)" \
 	    "@enable_multilib@" \
 	    > tmp-mlib.h; \
 	else \
-	  $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' '' '' "$(MULTIARCH_DIRNAME)" no \
+	  $(SHELL) $(srcdir)/genmultilib '' '' '' '' '' '' '' '' \
+	    "$(MULTIARCH_DIRNAME)" '' no \
 	    > tmp-mlib.h; \
 	fi
 	$(SHELL) $(srcdir)/../move-if-change tmp-mlib.h multilib.h
diff --git a/gcc/doc/fragments.texi b/gcc/doc/fragments.texi
index 28cef68..6985ac9 100644
--- a/gcc/doc/fragments.texi
+++ b/gcc/doc/fragments.texi
@@ -150,6 +150,35 @@ The @code{MULTILIB_REQUIRED} can be used together with
 @code{MULTILIB_OPTIONS} will be filtered by @code{MULTILIB_EXCEPTIONS}
 and then by @code{MULTILIB_REQUIRED}.
 
+@findex MULTILIB_REUSE
+@item MULTILIB_REUSE
+Sometimes it is desirable to reuse one existing multilib for different
+sets of options.  Such kind of reuse can minimize the number of multilib
+variants.  And for some targets it is better to reuse an existing multilib
+than to fall back to default multilib when there is no corresponding multilib.
+This can be done by adding reuse rules to @code{MULTILIB_REUSE}.
+
+A reuse rule is comprised of two parts connected by equality sign.  The left part
+is option set used to build multilib and the right part is option set that will
+reuse this multilib.  The order of options in the left part matters and should be
+same with those specified in @code{MULTILIB_REQUIRED} or aligned with order in
+@code{MULTILIB_OPTIONS}.  There is no such limitation for options in right part
+as we don't build multilib from them.  But the equality sign in both parts should
+be replaced with period.
+
+The @code{MULTILIB_REUSE} is different from @code{MULTILIB_MATCHES} in that it
+sets up relations between two option sets rather than two options.  Here is an
+example to demo how we reuse libraries built in Thumb mode for applications built
+in ARM mode:
+@smallexample
+@code{MULTILIB_REUSE} = mthumb/march.armv7-r=marm/march.armv7-r
+@end smallexample
+
+Before the advent of @code{MULTILIB_REUSE}, GCC select multilib by comparing command
+line options with options used to build multilib.  The @code{MULTILIB_REUSE} is
+complementary to that way.  Only when the original comparison matches nothing it will
+work to see if it is OK to reuse some existing multilib.
+
 @findex MULTILIB_EXTRA_OPTS
 @item MULTILIB_EXTRA_OPTS
 Sometimes it is desirable that when building multiple versions of
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 13e93e5..94d2678 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -857,6 +857,7 @@ static const char *multilib_select;
 static const char *multilib_matches;
 static const char *multilib_defaults;
 static const char *multilib_exclusions;
+static const char *multilib_reuse;
 
 /* Check whether a particular argument is a default argument.  */
 
@@ -1250,6 +1251,7 @@ static struct spec_list static_specs[] =
   INIT_STATIC_SPEC ("multilib_matches",		&multilib_matches),
   INIT_STATIC_SPEC ("multilib_exclusions",	&multilib_exclusions),
   INIT_STATIC_SPEC ("multilib_options",		&multilib_options),
+  INIT_STATIC_SPEC ("multilib_reuse",		&multilib_reuse),
   INIT_STATIC_SPEC ("linker",			&linker_name_spec),
   INIT_STATIC_SPEC ("linker_plugin_file",	&linker_plugin_file_spec),
   INIT_STATIC_SPEC ("lto_wrapper",		&lto_wrapper_spec),
@@ -6325,6 +6327,13 @@ main (int argc, char **argv)
     obstack_1grow (&multilib_obstack, 0);
     multilib_exclusions = XOBFINISH (&multilib_obstack, const char *);
 
+    q = multilib_reuse_raw;
+    while ((p = *q++) != (char *) 0)
+      obstack_grow (&multilib_obstack, p, strlen (p));
+
+    obstack_1grow (&multilib_obstack, 0);
+    multilib_reuse = XOBFINISH (&multilib_obstack, const char *);
+
     need_space = FALSE;
     for (i = 0; i < ARRAY_SIZE (multilib_defaults_raw); i++)
       {
@@ -7538,6 +7547,12 @@ set_multilib_dir (void)
 
   first = 1;
   p = multilib_select;
+
+  /* Append multilib reuse rules if any.  With those rules, we can reuse
+     one multilib for certain different options sets.  */
+  if (strlen (multilib_reuse) > 0)
+    p = concat (p, multilib_reuse, NULL);
+
   while (*p != '\0')
     {
       /* Ignore newlines.  */
@@ -7554,8 +7569,8 @@ set_multilib_dir (void)
 	  if (*p == '\0')
 	    {
 	    invalid_select:
-	      fatal_error ("multilib select %qs is invalid",
-			   multilib_select);
+	      fatal_error ("multilib select %qs %qs is invalid",
+			   multilib_select, multilib_reuse);
 	    }
 	  ++p;
 	}
diff --git a/gcc/genmultilib b/gcc/genmultilib
index 6ed1855..186d673 100644
--- a/gcc/genmultilib
+++ b/gcc/genmultilib
@@ -86,6 +86,9 @@
 
 # The optional ninth argument is the multiarch name.
 
+# The optional tenth argument specifies how to reuse multilib for different
+# option sets.
+
 # The last option should be "yes" if multilibs are enabled.  If it is not
 # "yes", all GCC multilib dir names will be ".".
 
@@ -106,7 +109,7 @@
 #   genmultilib 'm64/m32 mno-app-regs|mcmodel=medany' '64 32 alt'
 #		'mcmodel?medany=mcmodel?medmid' 'm32/mno-app-regs* m32/mcmodel=*'
 #		'' 'm32/!m64/mno-app-regs m32/!m64/mcmodel=medany'
-#		'../lib64 ../lib32 alt' '' yes
+#		'../lib64 ../lib32 alt' '' '' '' yes
 # This produces:
 #   ". !m64 !m32 !mno-app-regs !mcmodel=medany;",
 #   "64:../lib64 m64 !m32 !mno-app-regs !mcmodel=medany;",
@@ -136,7 +139,8 @@ exclusions=$6
 osdirnames=$7
 multilib_required=$8
 multiarch=$9
-enable_multilib=${10}
+multilib_reuse=${10}
+enable_multilib=${11}
 
 echo "static const char *const multilib_raw[] = {"
 
@@ -447,6 +451,35 @@ done
 echo "NULL"
 echo "};"
 
+# Output rules used for multilib reuse.
+echo ""
+echo "static const char *const multilib_reuse_raw[] = {"
+for rrule in ${multilib_reuse}; do
+  # The left part of the rule are the options we used to build multilib.
+  # The right part of the rule are the options that can reuse this multilib.
+  combo=`echo ${rrule} | sed -e 's/=.*$//' -e 's/\./=/g'`
+  copts=`echo ${rrule} | sed -e 's/^.*=//' -e 's/\./=/g'`
+  # The variable ${combinations} are the option combinations we will build
+  # multilib from.  If the combination in the left part of reuse rule isn't
+  # in this variable, it means no multilib will be built for current reuse
+  # rule.  Thus the reuse purpose specified by current rule is meaningless.
+  if expr "${combinations} " : ".*/${combo}/.*" > /dev/null; then
+    combo="/${combo}/"
+    dirout=`./tmpmultilib3 "${combo}" "${todirnames}" "${toosdirnames}" "${enable_multilib}"`
+    copts="/${copts}/"
+    optout=`./tmpmultilib4 "${copts}" "${options}"`
+    # Output the line with all appropriate matches.
+    dirout="${dirout}" optout="${optout}" ./tmpmultilib2
+  else
+    echo "The rule ${rrule} is trying to reuse nonexistent multilib."
+    exit 1
+  fi
+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 semicolon trailer.  Include all of the normal options as well.
 # Note, the format of the matches is reversed compared

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: [RFC] New feature to reuse one multilib among different targets
  2012-12-07 13:24               ` Terry Guo
@ 2013-01-07 16:13                 ` Joseph S. Myers
  2013-01-13 10:28                   ` Terry Guo
  0 siblings, 1 reply; 13+ messages in thread
From: Joseph S. Myers @ 2013-01-07 16:13 UTC (permalink / raw)
  To: Terry Guo; +Cc: gcc-patches

On Fri, 7 Dec 2012, Terry Guo wrote:

> 2012-12-07  Terry Guo  <terry.guo@arm.com>
> 
>         * gcc/Makefile.in (s-mlib): New argument MULTILIB_REUSE.
>         * gcc/doc/fragments.texi: Document MULTILIB_REUSE.
>         * gcc/gcc.c (multilib_reuse): New internal spec.
>         (set_multilib_dir): Also search multilib from multilib_reuse.
>         * gcc/genmultilib (tmpmultilib3): Refactor code.
>         (tmpmultilib4): Ditto.
>         (multilib_reuse): New multilib argument.

This patch is OK.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: [RFC] New feature to reuse one multilib among different targets
  2013-01-07 16:13                 ` Joseph S. Myers
@ 2013-01-13 10:28                   ` Terry Guo
  0 siblings, 0 replies; 13+ messages in thread
From: Terry Guo @ 2013-01-13 10:28 UTC (permalink / raw)
  To: 'Joseph Myers'; +Cc: gcc-patches



> -----Original Message-----
> From: Joseph Myers [mailto:joseph@codesourcery.com]
> Sent: Tuesday, January 08, 2013 12:13 AM
> To: Terry Guo
> Cc: gcc-patches@gcc.gnu.org
> Subject: RE: [RFC] New feature to reuse one multilib among different
targets
> 
> On Fri, 7 Dec 2012, Terry Guo wrote:
> 
> > 2012-12-07  Terry Guo  <terry.guo@arm.com>
> >
> >         * gcc/Makefile.in (s-mlib): New argument MULTILIB_REUSE.
> >         * gcc/doc/fragments.texi: Document MULTILIB_REUSE.
> >         * gcc/gcc.c (multilib_reuse): New internal spec.
> >         (set_multilib_dir): Also search multilib from multilib_reuse.
> >         * gcc/genmultilib (tmpmultilib3): Refactor code.
> >         (tmpmultilib4): Ditto.
> >         (multilib_reuse): New multilib argument.
> 
> This patch is OK.
> 

Thanks very much for review. Since there is no objection over the past days,
I just committed those patches to trunk.

BR,
Terry


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2013-01-13 10:28 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-10-10  7:58 [RFC] New feature to reuse one multilib among different targets Terry Guo
2012-10-10 14:59 ` Joseph S. Myers
2012-11-08  1:37   ` Terry Guo
2012-11-08 21:11     ` Joseph S. Myers
2012-11-09  7:36       ` Terry Guo
2012-11-09 16:35         ` Joseph S. Myers
2012-11-13  4:47           ` Terry Guo
2012-11-23  9:12             ` Ping: " Terry Guo
2012-12-04  2:36               ` Ping-2: " Terry Guo
2012-12-06 18:04             ` Joseph S. Myers
2012-12-07 13:24               ` Terry Guo
2013-01-07 16:13                 ` Joseph S. Myers
2013-01-13 10:28                   ` Terry Guo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).