diff mbox series

JIT, testsuite, Darwin: Initial testsuite fixes.

Message ID B7F72FD3-FFEE-4B13-B012-942C10ADC5E7@sandoe.co.uk
State New
Headers show
Series JIT, testsuite, Darwin: Initial testsuite fixes. | expand

Commit Message

Iain Sandoe Aug. 18, 2021, 7:40 p.m. UTC
Hi,

* Note, the strategy in jit.exp has the assumption that $target==$host
  the patches here adhere to that - there is far less testsuite library
  support for host-side facilities (which we’d probably want to add if
  it was desirable to operate the Jit in a cross-compiler environment).

-------

The testsuite setup for jit is not compatible with Darwin since it
assumes that all targets support --export-dynamic.

 - this is fixed by adding '-rdynamic' conditionally upon target
   support for that (-rdynamic will be converted to the appropriate
   linker option).
  
There is also an assumption that a suitable version of dejagnu.h
is present in some default include search path that is usable from
the testsuite.  This is not the case for Darwin (dejagnu.h is not
installed, and would not, in general, be found in any default  include
search path if installed via one of the main 'distros').  Also, the
upstream dejagnu.h has a definition of 'wait()' that clashes with a
libc routines and therefore causes fails in the testsuite.

 - This patch imports the header from dejagnu-1.6.2 and
   * renames it to 'jit-dejagnu.h'
   * patches it to avoid unused variable warnings and the clash
     with the libc definition of wait ()
   * In accordance with the advice in the expect man page, ensures
     that the final output of the 'totals' print is stable.

tested on i686, x86_64-darwin, x86_64, powerpc64-linux,
OK for master?
thanks
Iain

---

Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>

gcc/jit/ChangeLog:

	* jit-dejagnu.h: New file, imported from dejagnu-1.6.2 and
	patched for this application.

gcc/testsuite/ChangeLog:

	* jit.dg/jit.exp: Use -rdynamic conditionally on target
	support, instead of unconditional -Wl,--export-dynamic.
---
 gcc/jit/docs/examples/tut04-toyvm/toyvm.c  |   2 +-
 gcc/jit/docs/examples/tut04-toyvm/toyvm.cc |   2 +-
 gcc/jit/jit-dejagnu.h                      | 338 +++++++++++++++++++++
 gcc/testsuite/jit.dg/harness.h             |   2 +-
 gcc/testsuite/jit.dg/jit.exp               |   7 +-
 5 files changed, 347 insertions(+), 4 deletions(-)
 create mode 100644 gcc/jit/jit-dejagnu.h

Comments

David Malcolm Aug. 18, 2021, 7:54 p.m. UTC | #1
On Wed, 2021-08-18 at 20:40 +0100, Iain Sandoe wrote:
> Hi,
> 
> * Note, the strategy in jit.exp has the assumption that
> $target==$host
>   the patches here adhere to that - there is far less testsuite
> library
>   support for host-side facilities (which we’d probably want to add
> if
>   it was desirable to operate the Jit in a cross-compiler
> environment).

Various people have expressed wanting to use libgccjit for ahead-of-
time cross-compilation, so that's a use-case we're going to want to
support at some point (e.g. the libgccjit-based rustc backend).

> 
> -------
> 
> The testsuite setup for jit is not compatible with Darwin since it
> assumes that all targets support --export-dynamic.
> 
>  - this is fixed by adding '-rdynamic' conditionally upon target
>    support for that (-rdynamic will be converted to the appropriate
>    linker option).
>   
> There is also an assumption that a suitable version of dejagnu.h
> is present in some default include search path that is usable from
> the testsuite.  This is not the case for Darwin (dejagnu.h is not
> installed, and would not, in general, be found in any default 
> include
> search path if installed via one of the main 'distros').  Also, the
> upstream dejagnu.h has a definition of 'wait()' that clashes with a
> libc routines and therefore causes fails in the testsuite.
> 
>  - This patch imports the header from dejagnu-1.6.2 and
>    * renames it to 'jit-dejagnu.h'
>    * patches it to avoid unused variable warnings and the clash
>      with the libc definition of wait ()
>    * In accordance with the advice in the expect man page, ensures
>      that the final output of the 'totals' print is stable.
> 
> tested on i686, x86_64-darwin, x86_64, powerpc64-linux,
> OK for master?

[...snip...]

> diff --git a/gcc/jit/docs/examples/tut04-toyvm/toyvm.c
> b/gcc/jit/docs/examples/tut04-toyvm/toyvm.c
> index e742f344068..8ea716e2d0a 100644
> --- a/gcc/jit/docs/examples/tut04-toyvm/toyvm.c
> +++ b/gcc/jit/docs/examples/tut04-toyvm/toyvm.c
> @@ -24,7 +24,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include <stdlib.h>
>  #include <string.h>
>  
> -#include <dejagnu.h>
> +#include "jit-dejagnu.h"
>  
>  #include <libgccjit.h>
>  
> diff --git a/gcc/jit/docs/examples/tut04-toyvm/toyvm.cc
> b/gcc/jit/docs/examples/tut04-toyvm/toyvm.cc
> index 4b9c7651ee3..7e9550159ad 100644
> --- a/gcc/jit/docs/examples/tut04-toyvm/toyvm.cc
> +++ b/gcc/jit/docs/examples/tut04-toyvm/toyvm.cc
> @@ -24,7 +24,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include <stdlib.h>
>  #include <string.h>
>  
> -#include <dejagnu.h>
> +#include "jit-dejagnu.h"
>  
>  #include <libgccjit++.h>
>  

There's a Makefile in gcc/jit/docs/examples/tut04-toyvm which can be
used to build these, so do the
  #include "jit-dejagnu.h"
will need to be adjusted to give a path that finds the new header?

That said, the Makefile seems to assume pkg-config, so it's not working
particularly well as-is, so maybe there's no need to fix this.

Other than that nit, looks good to me.

test-threads.c does some preprocessor hackery to make <dejagnu.h>
threadsafe which it would be nice to fix, but that feels like followup
work and not needed for this patch.

Thanks
Dave
Iain Sandoe Aug. 19, 2021, 8:34 a.m. UTC | #2
Hi David,

> On 18 Aug 2021, at 20:54, David Malcolm via Gcc-patches <gcc-patches@gcc.gnu.org> wrote:
> 
> On Wed, 2021-08-18 at 20:40 +0100, Iain Sandoe wrote:
>> Hi,
>> 
>> * Note, the strategy in jit.exp has the assumption that
>> $target==$host
>>   the patches here adhere to that - there is far less testsuite
>> library
>>   support for host-side facilities (which we’d probably want to add
>> if
>>   it was desirable to operate the Jit in a cross-compiler
>> environment).
> 
> Various people have expressed wanting to use libgccjit for ahead-of-
> time cross-compilation, so that's a use-case we're going to want to
> support at some point (e.g. the libgccjit-based rustc backend).

ack.
That will be interesting to arrange; e.g. there will have to be some way to
find N host-side libraries that correspond to N cross-toolchains + 1 host-
side library that generates code for the host as a target.  Given that we
can only have one backend per library - although a standard toolchain
layout can accommodate multiple cross-toolchains + the native.

Probably, there’s a fair amount of test-suite library work to do to make it
possible to query similar capability information about the host (to that that
we currently query for targets).

Finally, I guess, some way of offloading the built objects to the cross-target
so that the execute portion can be done.

>> ———
[snip]

>> diff --git a/gcc/jit/docs/examples/tut04-toyvm/toyvm.cc
>> b/gcc/jit/docs/examples/tut04-toyvm/toyvm.cc
>> index 4b9c7651ee3..7e9550159ad 100644
>> --- a/gcc/jit/docs/examples/tut04-toyvm/toyvm.cc
>> +++ b/gcc/jit/docs/examples/tut04-toyvm/toyvm.cc
>> @@ -24,7 +24,7 @@ along with GCC; see the file COPYING3.  If not see
>>  #include <stdlib.h>
>>  #include <string.h>
>>  
>> -#include <dejagnu.h>
>> +#include "jit-dejagnu.h"
>>  
>>  #include <libgccjit++.h>
>>  
> 
> There's a Makefile in gcc/jit/docs/examples/tut04-toyvm which can be
> used to build these, so do the
>  #include "jit-dejagnu.h"
> will need to be adjusted to give a path that finds the new header?

> That said, the Makefile seems to assume pkg-config, so it's not working
> particularly well as-is, so maybe there's no need to fix this.

I don’t think that the current Makefile has any provision for finding dejagnu.h;
It will happen to work if that header is in one of the default include search
paths - but not otherwise.

Given that the Makefile seems to be designed for building the examples in-
source, I could make a patch that adds -I ../../.. to it to include the jit root?

Or we could symlink it - although presumably that would not work for hosts
that do not support symlinks.

> test-threads.c does some preprocessor hackery to make <dejagnu.h>
> threadsafe which it would be nice to fix, but that feels like followup
> work and not needed for this patch.

thanks, I’ve applied it as-is - but happy to make one of the two changes above
to the tut04 Makefile.

thanks,
Iain
diff mbox series

Patch

diff --git a/gcc/jit/docs/examples/tut04-toyvm/toyvm.c b/gcc/jit/docs/examples/tut04-toyvm/toyvm.c
index e742f344068..8ea716e2d0a 100644
--- a/gcc/jit/docs/examples/tut04-toyvm/toyvm.c
+++ b/gcc/jit/docs/examples/tut04-toyvm/toyvm.c
@@ -24,7 +24,7 @@  along with GCC; see the file COPYING3.  If not see
 #include <stdlib.h>
 #include <string.h>
 
-#include <dejagnu.h>
+#include "jit-dejagnu.h"
 
 #include <libgccjit.h>
 
diff --git a/gcc/jit/docs/examples/tut04-toyvm/toyvm.cc b/gcc/jit/docs/examples/tut04-toyvm/toyvm.cc
index 4b9c7651ee3..7e9550159ad 100644
--- a/gcc/jit/docs/examples/tut04-toyvm/toyvm.cc
+++ b/gcc/jit/docs/examples/tut04-toyvm/toyvm.cc
@@ -24,7 +24,7 @@  along with GCC; see the file COPYING3.  If not see
 #include <stdlib.h>
 #include <string.h>
 
-#include <dejagnu.h>
+#include "jit-dejagnu.h"
 
 #include <libgccjit++.h>
 
diff --git a/gcc/jit/jit-dejagnu.h b/gcc/jit/jit-dejagnu.h
new file mode 100644
index 00000000000..04608bfd879
--- /dev/null
+++ b/gcc/jit/jit-dejagnu.h
@@ -0,0 +1,338 @@ 
+/* DejaGnu unit testing header.
+   Copyright (C) 2000-2016 Free Software Foundation, Inc.
+
+This file is part of DejaGnu.
+
+DejaGnu is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+
+DejaGnu is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with DejaGnu; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+/* Imported from 1.6.2 with modifications
+   * to avoid and unused symbol in C compilations
+   * avoid wait () clashing with system-provided routines
+   * provide a deterministic last line of output after the totals.  */
+
+#ifndef __DEJAGNU_H__
+#define __DEJAGNU_H__
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+/* If you have problems with DejaGnu dropping failed, untested, or
+ * unresolved messages generated by a unit testcase, then:  */
+
+/* #define _DEJAGNU_WAIT_  */
+
+#ifdef _DEJAGNU_WAIT_
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+
+static int passed;
+static int failed;
+static int untest;
+static int unresolve;
+static int xfailed;
+#ifdef __cplusplus
+static int xpassed;
+#endif
+ 
+static char buffer[512];
+
+#ifdef _DEJAGNU_WAIT_
+void
+dg_wait (void)
+{
+  fd_set rfds;
+  struct timeval tv;
+
+  FD_ZERO (&rfds);
+  tv.tv_sec = 0;
+  tv.tv_usec = 1;
+
+  select (0, &rfds, NULL, NULL, &tv);
+}
+#endif
+
+static inline void
+pass (const char* fmt, ...)
+{
+  va_list ap;
+
+  passed++;
+  va_start (ap, fmt);
+  vsnprintf (buffer, sizeof (buffer), fmt, ap);
+  va_end (ap);
+  printf ("\tPASSED: %s\n", buffer);
+#ifdef _DEJAGNU_WAIT_
+  dg_wait ();
+#endif
+}
+
+static inline void
+xpass (const char* fmt, ...)
+{
+  va_list ap;
+
+  passed++;
+  va_start (ap, fmt);
+  vsnprintf (buffer, sizeof (buffer), fmt, ap);
+  va_end (ap);
+  printf ("\tXPASSED: %s\n", buffer);
+#ifdef _DEJAGNU_WAIT_
+  dg_wait ();
+#endif
+}
+
+static inline void
+fail (const char* fmt, ...)
+{
+  va_list ap;
+
+  failed++;
+  va_start (ap, fmt);
+  vsnprintf (buffer, sizeof (buffer), fmt, ap);
+  va_end (ap);
+  printf ("\tFAILED: %s\n", buffer);
+#ifdef _DEJAGNU_WAIT_
+  dg_wait ();
+#endif
+}
+
+static inline void
+xfail (const char* fmt, ...)
+{
+  va_list ap;
+
+  failed++;
+  va_start (ap, fmt);
+  vsnprintf (buffer, sizeof (buffer), fmt, ap);
+  va_end (ap);
+  printf ("\tXFAILED: %s\n", buffer);
+#ifdef _DEJAGNU_WAIT_
+  dg_wait ();
+#endif
+}
+
+static inline void
+untested (const char* fmt, ...)
+{
+  va_list ap;
+
+  untest++;
+  va_start (ap, fmt);
+  vsnprintf (buffer, sizeof (buffer), fmt, ap);
+  va_end (ap);
+  printf ("\tUNTESTED: %s\n", buffer);
+#ifdef _DEJAGNU_WAIT_
+  dg_wait ();
+#endif
+}
+
+static inline void
+unresolved (const char* fmt, ...)
+{
+  va_list ap;
+
+  unresolve++;
+  va_start (ap, fmt);
+  vsnprintf (buffer, sizeof (buffer), fmt, ap);
+  va_end (ap);
+  printf ("\tUNRESOLVED: %s\n", buffer);
+#ifdef _DEJAGNU_WAIT_
+  dg_wait ();
+#endif
+}
+
+static inline void
+note (const char* fmt, ...)
+{
+  va_list ap;
+
+  va_start (ap, fmt);
+  vsnprintf (buffer, sizeof (buffer), fmt, ap);
+  va_end (ap);
+  printf ("\tNOTE: %s\n", buffer);
+#ifdef _DEJAGNU_WAIT_
+  dg_wait ();
+#endif
+}
+
+static inline void
+totals (void)
+{
+  printf ("\nTotals:\n");
+  printf ("\t#passed:\t\t%d\n", passed);
+  printf ("\t#real failed:\t\t%d\n", failed);
+  if (xfailed)
+    printf ("\t#expected failures:\t\t%d\n", xfailed);
+  if (untest)
+    printf ("\t#untested:\t\t%d\n", untest);
+  if (unresolve)
+    printf ("\t#unresolved:\t\t%d\n", unresolve);
+  printf ("\njit-dg-harness-complete\n");
+}
+
+#ifdef __cplusplus
+
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include <string>
+
+const char *outstate_list[] = {
+  "FAILED: ", "PASSED: ", "UNTESTED: ", "UNRESOLVED: ", "XFAILED: ", "XPASSED: "
+};
+
+const char ** outstate = outstate_list;
+
+enum teststate { FAILED, PASSED, UNTESTED, UNRESOLVED, XFAILED, XPASSED} laststate;
+
+class TestState {
+ private:
+  teststate laststate;
+  std::string lastmsg;
+ public:
+  TestState (void)
+    {
+      passed = 0;
+      failed = 0;
+      untest = 0;
+      xpassed = 0;
+      xfailed = 0;
+      unresolve = 0;
+    }
+
+  ~TestState (void) { totals(); }
+
+  void testrun (bool b, std::string s)
+    {
+      if (b)
+	pass (s);
+      else
+	fail (s);
+    }
+
+    void pass (std::string s)
+      {
+	passed++;
+	laststate = PASSED;
+	lastmsg = s;
+	std::cout << "\t" << outstate[PASSED] << s << std::endl;
+      }
+
+    void pass (const char *c)
+      {
+	std::string s = c;
+	pass (s);
+      }
+
+    void xpass (std::string s)
+      {
+	xpassed++;
+	laststate = PASSED;
+	lastmsg = s;
+	std::cout << "\t" << outstate[XPASSED] << s << std::endl;
+      }
+
+    void xpass (const char *c)
+      {
+	std::string s = c;
+	xpass (s);
+      }
+
+    void fail (std::string s)
+      {
+	failed++;
+	laststate = FAILED;
+	lastmsg = s;
+	std::cout << "\t" << outstate[FAILED] << s << std::endl;
+      }
+
+    void fail (const char *c)
+      {
+	std::string s = c;
+	fail (s);
+      }
+
+    void xfail (std::string s)
+      {
+	xfailed++;
+	laststate = XFAILED;
+	lastmsg = s;
+	std::cout << "\t" << outstate[XFAILED] << s << std::endl;
+      }
+
+    void xfail (const char *c)
+      {
+	std::string s = c;
+	xfail (s);
+      }
+
+    void untested (std::string s)
+      {
+	untest++;
+	laststate = UNTESTED;
+	lastmsg = s;
+	std::cout << "\t" << outstate[UNTESTED] << s << std::endl;
+      }
+
+    void untested (const char *c)
+      {
+	std::string s = c;
+	untested (s);
+      }
+
+    void unresolved (std::string s)
+      {
+	unresolve++;
+	laststate = UNRESOLVED;
+	lastmsg = s;
+	std::cout << "\t" << outstate[UNRESOLVED] << s << std::endl;
+      }
+
+    void unresolved (const char *c)
+      {
+	std::string s = c;
+	unresolved (s);
+      }
+
+    void totals (void)
+      {
+	std::cout << "\t#passed:\t\t" << passed << std::endl;
+	std::cout << "\t#real failed:\t\t" << failed << std::endl;
+	if (xfailed)
+	  std::cout << "\t#expected failures:\t\t" << xfailed << std::endl;
+	if (xpassed)
+	  std::cout << "\t#unexpected passes:\t\t" << xpassed << std::endl;
+	if (untest)
+	  std::cout << "\t#untested:\t\t" << untest << std::endl;
+	if (unresolve)
+	  std::cout << "\t#unresolved:\t\t" << unresolve << std::endl;
+        std::cout << "\njit-dg-harness-complete" << std::endl;
+      }
+
+    // This is so this class can be printed in an ostream.
+    friend std::ostream & operator << (std::ostream &os, TestState& t)
+      {
+	return os << "\t" << outstate[t.laststate] << t.lastmsg ;
+      }
+
+    int GetState (void) { return laststate; }
+    std::string GetMsg (void) { return lastmsg; }
+};
+
+#endif /* __cplusplus */
+#endif /* _DEJAGNU_H_ */
diff --git a/gcc/testsuite/jit.dg/harness.h b/gcc/testsuite/jit.dg/harness.h
index 6b59fb57aae..0dc5ed1dad0 100644
--- a/gcc/testsuite/jit.dg/harness.h
+++ b/gcc/testsuite/jit.dg/harness.h
@@ -27,7 +27,7 @@ 
 #define note dejagnu_note
 #endif
 
-#include <dejagnu.h>
+#include "jit-dejagnu.h"
 
 #ifdef MAKE_DEJAGNU_H_THREADSAFE
 #undef pass
diff --git a/gcc/testsuite/jit.dg/jit.exp b/gcc/testsuite/jit.dg/jit.exp
index 9af87f9c6ad..005ba01601a 100644
--- a/gcc/testsuite/jit.dg/jit.exp
+++ b/gcc/testsuite/jit.dg/jit.exp
@@ -914,9 +914,14 @@  proc jit-verify-executable { args } {
     jit-run-executable $output_filename ${dg-output-text}
 }
 
+set DEFAULT_CFLAGS "-I$srcdir/../jit -lgccjit -g -Wall -Werror"
+
 # We need to link with --export-dynamic for test-calling-external-function.c
 # so that the JIT-built code can call into functions from the main program.
-set DEFAULT_CFLAGS "-I$srcdir/../jit -lgccjit -g -Wall -Werror -Wl,--export-dynamic"
+
+if { [check_effective_target_rdynamic] } {
+  set DEFAULT_CFLAGS "$DEFAULT_CFLAGS -rdynamic"
+}
 
 # Main loop.  This will invoke jig-dg-test on each test-*.c file.
 dg-runtest $tests "" $DEFAULT_CFLAGS