Hello All,

As I explained in https://gcc.gnu.org/ml/jit/2016-q2/msg00042.html it is difficult (or tricky without using dirty tricks involving the GCC plugin headers) to use GCCJIT to emit code equivalent to the following C file:

   extern int a;
   int get_atomic_a (void) {
     return __atomic_load_n (&a, __ATOMIC_SEQ_CST);
   }

The issue is that __ATOMIC_SEQ_CST is a magic preprocessor (but non-standard!) 
symbol which might not be available
(or might have a different value) in the C code for GCCJIT building such an AST.

So we need a function to retrieve some magic integral value from the GCCJIT 
compiler.

The attached patch (relative to trunk svn 236583) is a first attempt to solve 
that issue
 (and also give ability to query some other magic numbers).

Proposed ChangeLog entry (in gcc/jit/)

2016-05-23  Basile Starynkevitch  <bas...@starynkevitch.net>
        * libgccjit.h (LIBGCCJIT_HAVE_gcc_jit_magic_int): New macro.
        (gcc_jit_magic_int): New public function declaration.

        * libgccjit.c: Include "cppbuiltin.h", "options.h", "flag-types.h"
        (gcc_jit_magic_int): New function.

        * libgccjit.map: Add gcc_jit_magic_int to LIBGCCJIT_ABI_6.

Comments (or an ok to commit) are welcome. (I am not sure that 
__SANITIZE_ADDRESS__ is correctly handled,
because I would believe that optimization flags are not globals in GCCJIT)

Regards.

--
Basile STARYNKEVITCH         http://starynkevitch.net/Basile/
email: basile<at>starynkevitch<dot>net mobile: +33 6 8501 2359
8, rue de la Faiencerie, 92340 Bourg La Reine, France
*** opinions {are only mine, sont seulement les miennes} ***

Index: gcc/jit/libgccjit.h
===================================================================
--- gcc/jit/libgccjit.h	(revision 236583)
+++ gcc/jit/libgccjit.h	(working copy)
@@ -1387,6 +1387,27 @@
 gcc_jit_rvalue_set_bool_require_tail_call (gcc_jit_rvalue *call,
 					   int require_tail_call);
 
+
+  /* Magical integer values useful in the compiler; similar to
+     predefined C macros like __GNUC__, __GNUC_MINOR__,
+     __GNUC_PATCHLEVEL__, __ATOMIC_RELAXED, __ATOMIC_SEQ_CST,
+     __ATOMIC_ACQUIRE, __ATOMIC_RELEASE, __ATOMIC_ACQ_REL,
+     __ATOMIC_CONSUME, __PIC__, __PIE__, etc.  Typical usage would be:
+
+    bool err=false;
+    int mypic = gcc_jit_magic_int("__PIC__", &err);
+    if (err) somethinggotwrong();
+
+    This function is expected to be rarely called, typically once at
+    initialization time. 
+
+   This API entrypoint was added in LIBGCCJIT_ABI_6; you can test for its
+   presence using
+     #ifdef LIBGCCJIT_HAVE_gcc_jit_magic_int
+  */
+#define LIBGCCJIT_HAVE_gcc_jit_magic_int
+extern int gcc_jit_magic_int(const char*name, bool*errp);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
Index: gcc/jit/libgccjit.c
===================================================================
--- gcc/jit/libgccjit.c	(revision 236583)
+++ gcc/jit/libgccjit.c	(working copy)
@@ -23,6 +23,9 @@
 #include "coretypes.h"
 #include "timevar.h"
 #include "typed-splay-tree.h"
+#include "cppbuiltin.h"
+#include "options.h"
+#include "flag-types.h"
 
 #include "libgccjit.h"
 #include "jit-recording.h"
@@ -2970,3 +2973,44 @@
 
   call->set_require_tail_call (require_tail_call);
 }
+
+
+/* Public entrypoint. See description in libgccjit.h. */
+
+int gcc_jit_magic_int(const char*name, bool*errp)
+{
+  static int major, minor, patchlevel;
+  if (!major) /* call once: */
+    parse_basever (&major, &minor, &patchlevel);
+  
+  RETURN_VAL_IF_FAIL (name,
+		      errp?((*errp=true),0):0,
+		      NULL, NULL,
+		      "NULL name");
+  RETURN_VAL_IF_FAIL (name[0] == '_' && name[1] == '_',
+		      errp?((*errp=true),0):0,
+		      NULL, NULL,
+		     "name should start with two underscores");
+#define HAVE_MAGIC_INT(NamStr,Val) do {		\
+  if (!strcmp(name, NamStr)) {			\
+  if (errp) *errp = false;			\
+  return Val; }} while(0)
+  // keep these in alphabetical order...
+  HAVE_MAGIC_INT("__ATOMIC_ACQUIRE", MEMMODEL_ACQUIRE);
+  HAVE_MAGIC_INT("__ATOMIC_ACQ_REL", MEMMODEL_ACQ_REL);
+  HAVE_MAGIC_INT("__ATOMIC_CONSUME", MEMMODEL_CONSUME);
+  HAVE_MAGIC_INT("__ATOMIC_RELAXED", MEMMODEL_RELAXED);
+  HAVE_MAGIC_INT("__ATOMIC_RELEASE", MEMMODEL_RELEASE);
+  HAVE_MAGIC_INT("__ATOMIC_SEQ_CST", MEMMODEL_SEQ_CST);
+  HAVE_MAGIC_INT("__GNUC_MINOR__", minor);
+  HAVE_MAGIC_INT("__GNUC_PATCHLEVEL__", patchlevel);
+  HAVE_MAGIC_INT("__GNUC__", major);
+  HAVE_MAGIC_INT("__PIC__", flag_pic);
+  HAVE_MAGIC_INT("__PIE__", flag_pie);
+  HAVE_MAGIC_INT("__SANITIZE_ADDRESS__", flag_sanitize & SANITIZE_ADDRESS);
+  HAVE_MAGIC_INT("__SANITIZE_THREAD__", flag_sanitize & SANITIZE_THREAD);
+#undef HAVE_MAGIC_INT
+  RETURN_VAL_IF_FAIL_PRINTF1 (false,  errp?((*errp=true),0):0,
+			      NULL, NULL,
+			      "unknown magic int name: %s", name);
+}
Index: gcc/jit/libgccjit.map
===================================================================
--- gcc/jit/libgccjit.map	(revision 236583)
+++ gcc/jit/libgccjit.map	(working copy)
@@ -149,4 +149,5 @@
 LIBGCCJIT_ABI_6 {
   global:
     gcc_jit_rvalue_set_bool_require_tail_call;
+    gcc_jit_magic_int;
 } LIBGCCJIT_ABI_5;

Reply via email to