public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fix driver handling of multiple -ftree-parallelize-loops=<n> options (PR driver/69805)
@ 2016-02-16 15:24 Jakub Jelinek
  2016-02-17  7:14 ` Tom de Vries
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Jakub Jelinek @ 2016-02-16 15:24 UTC (permalink / raw)
  To: gcc-patches; +Cc: Tom de Vries

Hi!

As mentioned in the PR, %{ftree-parallelize-loops=*} expands to
all -ftree-parallelize-loops= options, not just the last one.
So greater_than_spec_func is actually called say for
-ftree-parallelize-loops=0 -ftree-parallelize-loops=2 with
- ftree-parallelize-loops=0 - ftree-parallelize-loops=2 1
(each whitespace separated sequence separate arg), but it asserts
it sees just 3 arguments.
Passing the - and ftree-parallelize-loops= stuff looks weird,
and we have %* that substitutes just the variable part of the option,
so in addition to fixing the case of multiple options I've also changed
%:gt() behaviour, so that it now gets just the numbers and compares the
last two of them.  So for the above options it would be called with
0 2 1
and would compare
2 > 1
and return "", or for
-ftree-parallelize-loops=2 -ftree-parallelize-loops=0 -ftree-parallelize-loops=1
would be
2 0 1 1
and compare
1 > 1
and return NULL. %:gt() is not used anywhere else, and has been introduced
only in GCC 6.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2016-02-16  Jakub Jelinek  <jakub@redhat.com>

	PR driver/69805
	* gcc.c (LINK_COMMAND_SPEC, GOMP_SELF_SPECS): Use
	:%* in %:gt() argument.
	(greater_than_spec_func): Adjust for expecting only numbers,
	if there are more than two numbers, compare the last two.

	* testsuite/libgomp.c/pr69805.c: New test.

--- gcc/gcc.c.jj	2016-02-15 22:22:51.000000000 +0100
+++ gcc/gcc.c	2016-02-16 09:35:03.579849080 +0100
@@ -1019,7 +1019,7 @@ proper position among the other output f
     %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}} \
     %{static:} %{L*} %(mfwrap) %(link_libgcc) " \
     VTABLE_VERIFICATION_SPEC " " SANITIZER_EARLY_SPEC " %o " CHKP_SPEC " \
-    %{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*} 1):\
+    %{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*:%*} 1):\
 	%:include(libgomp.spec)%(link_gomp)}\
     %{fcilkplus:%:include(libcilkrts.spec)%(link_cilkrts)}\
     %{fgnu-tm:%:include(libitm.spec)%(link_itm)}\
@@ -1183,7 +1183,7 @@ static const char *const multilib_defaul
    for targets that use different start files and suchlike.  */
 #ifndef GOMP_SELF_SPECS
 #define GOMP_SELF_SPECS \
-  "%{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*} 1): " \
+  "%{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*:%*} 1): " \
   "-pthread}"
 #endif
 
@@ -9764,7 +9764,7 @@ replace_extension_spec_func (int argc, c
   return result;
 }
 
-/* Returns "" if the n in ARGV[1] == -opt=<n> is greater than ARGV[2].
+/* Returns "" if ARGV[ARGC - 2] is greater than ARGV[ARGC-1].
    Otherwise, return NULL.  */
 
 static const char *
@@ -9775,29 +9775,13 @@ greater_than_spec_func (int argc, const
   if (argc == 1)
     return NULL;
 
-  gcc_assert (argc == 3);
-  gcc_assert (argv[0][0] == '-');
-  gcc_assert (argv[0][1] == '\0');
-
-  /* Point p to <n> in in -opt=<n>.  */
-  const char *p = argv[1];
-  while (true)
-    {
-      char c = *p;
-      if (c == '\0')
-	gcc_unreachable ();
+  gcc_assert (argc >= 2);
 
-      ++p;
-
-      if (c == '=')
-	break;
-    }
-
-  long arg = strtol (p, &converted, 10);
-  gcc_assert (converted != p);
+  long arg = strtol (argv[argc - 2], &converted, 10);
+  gcc_assert (converted != argv[argc - 2]);
 
-  long lim = strtol (argv[2], &converted, 10);
-  gcc_assert (converted != argv[2]);
+  long lim = strtol (argv[argc - 1], &converted, 10);
+  gcc_assert (converted != argv[argc - 1]);
 
   if (arg > lim)
     return "";
--- libgomp/testsuite/libgomp.c/pr69805.c.jj	2016-02-16 09:54:46.928527601 +0100
+++ libgomp/testsuite/libgomp.c/pr69805.c	2016-02-16 09:55:29.453941023 +0100
@@ -0,0 +1,9 @@
+/* PR driver/69805 */
+/* { dg-do link } */
+/* { dg-options "-ftree-parallelize-loops=1 -O2 -ftree-parallelize-loops=2" } */
+
+int
+main ()
+{
+  return 0;
+}

	Jakub

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

* Re: [PATCH] Fix driver handling of multiple -ftree-parallelize-loops=<n> options (PR driver/69805)
  2016-02-16 15:24 [PATCH] Fix driver handling of multiple -ftree-parallelize-loops=<n> options (PR driver/69805) Jakub Jelinek
@ 2016-02-17  7:14 ` Tom de Vries
  2016-02-17 16:07   ` Sandra Loosemore
  2016-02-18 11:01 ` Tom de Vries
  2016-02-19 22:15 ` Jeff Law
  2 siblings, 1 reply; 7+ messages in thread
From: Tom de Vries @ 2016-02-17  7:14 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches, Sandra Loosemore

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

On 16/02/16 16:24, Jakub Jelinek wrote:
> Hi!
>
> As mentioned in the PR, %{ftree-parallelize-loops=*} expands to
> all -ftree-parallelize-loops= options, not just the last one.
> So greater_than_spec_func is actually called say for
> -ftree-parallelize-loops=0 -ftree-parallelize-loops=2 with
> - ftree-parallelize-loops=0 - ftree-parallelize-loops=2 1
> (each whitespace separated sequence separate arg), but it asserts
> it sees just 3 arguments.
> Passing the - and ftree-parallelize-loops= stuff looks weird,
> and we have %* that substitutes just the variable part of the option,
> so in addition to fixing the case of multiple options I've also changed
> %:gt() behaviour, so that it now gets just the numbers and compares the
> last two of them.  So for the above options it would be called with
> 0 2 1
> and would compare
> 2 > 1
> and return "", or for
> -ftree-parallelize-loops=2 -ftree-parallelize-loops=0 -ftree-parallelize-loops=1
> would be
> 2 0 1 1
> and compare
> 1 > 1
> and return NULL. %:gt() is not used anywhere else, and has been introduced
> only in GCC 6.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2016-02-16  Jakub Jelinek  <jakub@redhat.com>
>
> 	PR driver/69805
> 	* gcc.c (LINK_COMMAND_SPEC, GOMP_SELF_SPECS): Use
> 	:%* in %:gt() argument.
> 	(greater_than_spec_func): Adjust for expecting only numbers,
> 	if there are more than two numbers, compare the last two.
>
> 	* testsuite/libgomp.c/pr69805.c: New test.
>

Here's the documentation entry for the gt spec function (I forgot to add 
it when introducing the function), using the new semantics.

Copy-pasting from the resulting .info viewed in emacs for a 
human-readable version:
...
      'gt'
           The 'gt' (greater than) function takes one or more arguments.
           It returns either NULL or the empty string.  If it has one
           argument, it returns NULL.  If it has two arguments, it
           compares them: it returns the empty string if the first
           argument is greater than the second argument, otherwise it
           returns NULL.  If it has more than two arguments, it behaves
           as if only the last two arguments were passed.  It can be used
           f.i. as 'S' in a spec directive %{'S':'X'}: if 'S' is NULL,
           the empty string is substituted, and if 'S' is the empty
           string, 'X' is substituted.

                %:gt(%{fsome-option-value=*:%*} 1)
...

OK for stage4 trunk?

Thanks,
- Tom


[-- Attachment #2: 0001-Add-documentation-for-spec-function-gt-in-invoke.texi.patch --]
[-- Type: text/x-patch, Size: 1309 bytes --]

Add documentation for spec function gt in invoke.texi

2016-02-16  Tom de Vries  <tom@codesourcery.com>

	* doc/invoke.texi (@node Spec Files): Document spec function gt.

---
 gcc/doc/invoke.texi | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 666d976..2da7a72 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -24783,6 +24783,20 @@ Use "-Wa,OPTION" to pass "OPTION" to the assembler.
 
 It is used to separate compiler options from assembler options
 in the @option{--target-help} output.
+
+@item @code{gt}
+The @code{gt} (greater than) function takes one or more arguments.  It returns
+either NULL or the empty string.  If it has one argument, it returns NULL.@  If
+it has two arguments, it compares them: it returns the empty string if the first
+argument is greater than the second argument, otherwise it returns NULL.@  If it
+has more than two arguments, it behaves as if only the last two arguments were
+passed.  It can be used f.i.@ as @code{S} in a spec directive
+%@{@code{S}:@code{X}@}: if @code{S} is NULL, the empty string is substituted,
+and if @code{S} is the empty string, @code{X} is substituted.
+
+@smallexample
+%:gt(%@{fsome-option-value=*:%*@} 1)
+@end smallexample
 @end table
 
 @item %@{@code{S}@}

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

* Re: [PATCH] Fix driver handling of multiple -ftree-parallelize-loops=<n> options (PR driver/69805)
  2016-02-17  7:14 ` Tom de Vries
@ 2016-02-17 16:07   ` Sandra Loosemore
  2016-02-18 10:34     ` Jakub Jelinek
  2016-02-18 10:43     ` Tom de Vries
  0 siblings, 2 replies; 7+ messages in thread
From: Sandra Loosemore @ 2016-02-17 16:07 UTC (permalink / raw)
  To: Tom de Vries, Jakub Jelinek; +Cc: gcc-patches

On 02/17/2016 12:14 AM, Tom de Vries wrote:
>
> Here's the documentation entry for the gt spec function (I forgot to add
> it when introducing the function), using the new semantics.
>
> Copy-pasting from the resulting .info viewed in emacs for a
> human-readable version:
> ...
>       'gt'
>            The 'gt' (greater than) function takes one or more arguments.
>            It returns either NULL or the empty string.  If it has one
>            argument, it returns NULL.  If it has two arguments, it
>            compares them: it returns the empty string if the first
>            argument is greater than the second argument, otherwise it
>            returns NULL.  If it has more than two arguments, it behaves
>            as if only the last two arguments were passed.  It can be used
>            f.i. as 'S' in a spec directive %{'S':'X'}: if 'S' is NULL,
>            the empty string is substituted, and if 'S' is the empty
>            string, 'X' is substituted.
>
>                 %:gt(%{fsome-option-value=*:%*} 1)
> ...
>
> OK for stage4 trunk?

I'm not an expert on spec strings....  but from a user perspective, what 
is the difference between "NULL" and "the empty string"?  The other spec 
escapes are documented in terms of pattern substitutions at the point 
where the escape appears in the spec string.

-Sandra

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

* Re: [PATCH] Fix driver handling of multiple -ftree-parallelize-loops=<n> options (PR driver/69805)
  2016-02-17 16:07   ` Sandra Loosemore
@ 2016-02-18 10:34     ` Jakub Jelinek
  2016-02-18 10:43     ` Tom de Vries
  1 sibling, 0 replies; 7+ messages in thread
From: Jakub Jelinek @ 2016-02-18 10:34 UTC (permalink / raw)
  To: Sandra Loosemore; +Cc: Tom de Vries, gcc-patches

On Wed, Feb 17, 2016 at 09:07:42AM -0700, Sandra Loosemore wrote:
> On 02/17/2016 12:14 AM, Tom de Vries wrote:
> >
> >Here's the documentation entry for the gt spec function (I forgot to add
> >it when introducing the function), using the new semantics.
> >
> >Copy-pasting from the resulting .info viewed in emacs for a
> >human-readable version:
> >...
> >      'gt'
> >           The 'gt' (greater than) function takes one or more arguments.
> >           It returns either NULL or the empty string.  If it has one
> >           argument, it returns NULL.  If it has two arguments, it
> >           compares them: it returns the empty string if the first
> >           argument is greater than the second argument, otherwise it
> >           returns NULL.  If it has more than two arguments, it behaves
> >           as if only the last two arguments were passed.  It can be used
> >           f.i. as 'S' in a spec directive %{'S':'X'}: if 'S' is NULL,
> >           the empty string is substituted, and if 'S' is the empty
> >           string, 'X' is substituted.
> >
> >                %:gt(%{fsome-option-value=*:%*} 1)
> >...
> >
> >OK for stage4 trunk?
> 
> I'm not an expert on spec strings....  but from a user perspective, what is
> the difference between "NULL" and "the empty string"?  The other spec
> escapes are documented in terms of pattern substitutions at the point where
> the escape appears in the spec string.

NULL vs. "" is the internal (C level representation) of %:fn() function
returned false vs. true for the purpose of e.g. %{%:fn():...}.

	Jakub

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

* Re: [PATCH] Fix driver handling of multiple -ftree-parallelize-loops=<n> options (PR driver/69805)
  2016-02-17 16:07   ` Sandra Loosemore
  2016-02-18 10:34     ` Jakub Jelinek
@ 2016-02-18 10:43     ` Tom de Vries
  1 sibling, 0 replies; 7+ messages in thread
From: Tom de Vries @ 2016-02-18 10:43 UTC (permalink / raw)
  To: Sandra Loosemore, Jakub Jelinek; +Cc: GCC Patches

On 17/02/16 17:07, Sandra Loosemore wrote:
> On 02/17/2016 12:14 AM, Tom de Vries wrote:
>>
>> Here's the documentation entry for the gt spec function (I forgot to add
>> it when introducing the function), using the new semantics.
>>
>> Copy-pasting from the resulting .info viewed in emacs for a
>> human-readable version:
>> ...
>>       'gt'
>>            The 'gt' (greater than) function takes one or more arguments.
>>            It returns either NULL or the empty string.  If it has one
>>            argument, it returns NULL.  If it has two arguments, it
>>            compares them: it returns the empty string if the first
>>            argument is greater than the second argument, otherwise it
>>            returns NULL.  If it has more than two arguments, it behaves
>>            as if only the last two arguments were passed.  It can be used
>>            f.i. as 'S' in a spec directive %{'S':'X'}: if 'S' is NULL,
>>            the empty string is substituted, and if 'S' is the empty
>>            string, 'X' is substituted.
>>
>>                 %:gt(%{fsome-option-value=*:%*} 1)
>> ...
>>
>> OK for stage4 trunk?
>
> I'm not an expert on spec strings....  but from a user perspective, what
> is the difference between "NULL" and "the empty string"?  The other spec
> escapes are documented in terms of pattern substitutions at the point
> where the escape appears in the spec string.

Hi Sandra,

yes, that's a good point.


I.

The first time we used this type of "NULL"/"empty string" distinction 
was for the sanitize spec function, introduced here ( 
https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=0016189f560b1dc86734d36826be891562da1c46;hp=e9d78f5ab2b5a1cc50cd20ca2da199f83258b153 
) in the ubsan branch, which was later merged to trunk at r202113 (patch 
submitted here: https://gcc.gnu.org/ml/gcc-patches/2013-07/msg00510.html ).

The commit adds this text to 'The Specs Language' bit in gcc.c:
...
  %{%:function(args):X}
          Call function named FUNCTION with args ARGS.  If the function
          returns non-NULL, then X is substituted, if it returns
          NULL, it isn't substituted.
...

I suppose we should document this behavior first in invoke.texi, and we 
could choose user-oriented names for the NULL/non-NULL distinction.


II.

Furthermore, the implementation seems to be inconsistent with the 
specification. If I modify greater_than_spec_func to return non-NULL, 
but not the empty string:
...
@@ -9800,7 +9803,7 @@ greater_than_spec_func
    gcc_assert (converted != argv[2]);

    if (arg > lim)
-    return "";
+    return "true";

    return NULL;
  }
...

I get:
...
$ gcc hello.c -O2 -ftree-parallelize-loops=2
gcc: fatal error: switch ‘true’ does not start with ‘-’
compilation terminated.
...

This (otherwise untested) patch fixes that:
...
@@ -6068,10 +6068,13 @@ handle_spec_function
    /* p now points to just past the end of the spec function
       expression.  */

    funcval = eval_spec_function (func, args);
-  if (funcval != NULL && do_spec_1 (funcval, 0, NULL) < 0)
-    p = NULL;
    if (retval_nonnull)
      *retval_nonnull = funcval != NULL;
+  else
+    {
+      if (funcval != NULL && do_spec_1 (funcval, 0, NULL) < 0)
+       p = NULL;
+    }

    free (func);
    free (args);
...


III.

So, a spec function can return:
a: NULL,
b: empty string, and
c: non-empty string.

In the context of evaluating a spec function as a condition, NULL 
designates false, empty string designates true and if we fix the problem 
mentioned at II then also non-empty string designates true, so:
- false (a)
- true (b, c)

In the context of evaluating a spec function for the resulting string, 
NULL means an empty string (AFAICT), just like an empty string, so we have:
- empty (a, b)
- non-empty (c)

I think that's going to be hard to explain to the user.

It seems originally ( 
https://gcc.gnu.org/ml/gcc-patches/2013-06/msg01100.html ) the 
empty/non-empty string distinction was proposed for the semantics of 
'%{%:function(args):X}'. Perhaps we should consider a rewrite using that 
distinction.

Thanks,
- Tom

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

* Re: [PATCH] Fix driver handling of multiple -ftree-parallelize-loops=<n> options (PR driver/69805)
  2016-02-16 15:24 [PATCH] Fix driver handling of multiple -ftree-parallelize-loops=<n> options (PR driver/69805) Jakub Jelinek
  2016-02-17  7:14 ` Tom de Vries
@ 2016-02-18 11:01 ` Tom de Vries
  2016-02-19 22:15 ` Jeff Law
  2 siblings, 0 replies; 7+ messages in thread
From: Tom de Vries @ 2016-02-18 11:01 UTC (permalink / raw)
  To: Jakub Jelinek, gcc-patches

On 16/02/16 16:24, Jakub Jelinek wrote:
> Passing the - and ftree-parallelize-loops= stuff looks weird,
> and we have %* that substitutes just the variable part of the option,
> so in addition to fixing the case of multiple options I've also changed
> %:gt() behaviour, so that it now gets just the numbers and compares the
> last two of them.

FTR, version-compare uses yet another variant: It does not expect to be 
called with an %{S*} or %{S*:%*} expansion, but passes S as an argument:
...
%:version-compare(>= 10.3 mmacosx-version-min= -lmx)
...
and the spec function itself takes care of finding the last value.

Thanks,
- Tom

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

* Re: [PATCH] Fix driver handling of multiple -ftree-parallelize-loops=<n> options (PR driver/69805)
  2016-02-16 15:24 [PATCH] Fix driver handling of multiple -ftree-parallelize-loops=<n> options (PR driver/69805) Jakub Jelinek
  2016-02-17  7:14 ` Tom de Vries
  2016-02-18 11:01 ` Tom de Vries
@ 2016-02-19 22:15 ` Jeff Law
  2 siblings, 0 replies; 7+ messages in thread
From: Jeff Law @ 2016-02-19 22:15 UTC (permalink / raw)
  To: Jakub Jelinek, gcc-patches; +Cc: Tom de Vries

On 02/16/2016 08:24 AM, Jakub Jelinek wrote:
> Hi!
>
> As mentioned in the PR, %{ftree-parallelize-loops=*} expands to
> all -ftree-parallelize-loops= options, not just the last one.
> So greater_than_spec_func is actually called say for
> -ftree-parallelize-loops=0 -ftree-parallelize-loops=2 with
> - ftree-parallelize-loops=0 - ftree-parallelize-loops=2 1
> (each whitespace separated sequence separate arg), but it asserts
> it sees just 3 arguments.
> Passing the - and ftree-parallelize-loops= stuff looks weird,
> and we have %* that substitutes just the variable part of the option,
> so in addition to fixing the case of multiple options I've also changed
> %:gt() behaviour, so that it now gets just the numbers and compares the
> last two of them.  So for the above options it would be called with
> 0 2 1
> and would compare
> 2 > 1
> and return "", or for
> -ftree-parallelize-loops=2 -ftree-parallelize-loops=0 -ftree-parallelize-loops=1
> would be
> 2 0 1 1
> and compare
> 1 > 1
> and return NULL. %:gt() is not used anywhere else, and has been introduced
> only in GCC 6.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2016-02-16  Jakub Jelinek  <jakub@redhat.com>
>
> 	PR driver/69805
> 	* gcc.c (LINK_COMMAND_SPEC, GOMP_SELF_SPECS): Use
> 	:%* in %:gt() argument.
> 	(greater_than_spec_func): Adjust for expecting only numbers,
> 	if there are more than two numbers, compare the last two.
>
> 	* testsuite/libgomp.c/pr69805.c: New test.
I'll note that Tom ack'd in c#3, and he certainly know this 
functionality better than I.  So OK for trunk.

Jeff

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

end of thread, other threads:[~2016-02-19 22:15 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-16 15:24 [PATCH] Fix driver handling of multiple -ftree-parallelize-loops=<n> options (PR driver/69805) Jakub Jelinek
2016-02-17  7:14 ` Tom de Vries
2016-02-17 16:07   ` Sandra Loosemore
2016-02-18 10:34     ` Jakub Jelinek
2016-02-18 10:43     ` Tom de Vries
2016-02-18 11:01 ` Tom de Vries
2016-02-19 22:15 ` Jeff Law

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).