[PATCH, committed] New jit API entrypoint: gcc_jit_context_new_rvalue_from_long

David Malcolm dmalcolm@redhat.com
Fri Jan 9 20:20:00 GMT 2015


Previously it was only possible to create integer constants via
gcc_jit_context_new_rvalue_from_int [1], which takes a host "int" and
a gcc_jit_type representing a target type

Hence it wasn't possible to create e.g. the constant (long)LONG_MAX
if int != long.

(strictly speaking, one might be able to do it via the double and
void * entrypoints, but doing so would be error-prone).

Introduce new API entrypoint: gcc_jit_context_new_rvalue_from_long
which takes a host "long".

Internally, rework the constant-handling machinery to use templates,
which should make it easier to add further host types for constant
value e.g. longlong and the unsigned variants, if we need to.

This brings jit.sum to:
  # of expected passes       7152

Committed to trunk as r219401.

gcc/jit/ChangeLog:
	* docs/cp/topics/expressions.rst (Simple expressions): Use
	":c:type:" for C types.  Document new overload of
	gcc::jit::context::new_rvalue.
	* docs/topics/expressions.rst (Simple expressions): Use
	":c:type:" for C types.  Document new entrypoint
	gcc_jit_context_new_rvalue_from_long.
	* docs/_build/texinfo/libgccjit.texi: Regenerate.
	* jit-playback.c: Within namespace gcc::jit::playback...
	(context::new_rvalue_from_int): Eliminate in favor of...
	(context::new_rvalue_from_const <int>): ...this.
	(context::new_rvalue_from_double): Eliminate in favor of...
	(context::new_rvalue_from_const <double>): ...this.
	(context::new_rvalue_from_const <long>): New.
	(context::new_rvalue_from_ptr): Eliminate in favor of...
	(context::new_rvalue_from_const <void *>): ...this.
	* jit-playback.h: Within namespace gcc::jit::playback...
	(context::new_rvalue_from_int): Eliminate in favor of...
	(context::new_rvalue_from_const <HOST_TYPE>): ...this.
	(context::new_rvalue_from_double): Likewise.
	(context::new_rvalue_from_ptr): Likewise.
	* jit-recording.c: Within namespace gcc::jit::recording...
	(context::new_rvalue_from_int): Eliminate.
	(context::new_rvalue_from_double): Likewise.
	(context::new_rvalue_from_ptr): Likewise.
	(class memento_of_new_rvalue_from_const <int>):
	Add explicit specialization.
	(class memento_of_new_rvalue_from_const <long>):
	Likewise.
	(class memento_of_new_rvalue_from_const <double>):
	Likewise.
	(class memento_of_new_rvalue_from_const <void *>):
	Likewise.
	(memento_of_new_rvalue_from_int::replay_into):
	Generalize into...
	(memento_of_new_rvalue_from_const <HOST_TYPE>::replay_into):
	...this...
	(memento_of_new_rvalue_from_double::replay_into):
	...allowing this...
	(memento_of_new_rvalue_from_ptr::replay_into):
	...and this to be deleted.
	(memento_of_new_rvalue_from_int::make_debug_string):
	Convert to...
	(memento_of_new_rvalue_from_const <int>::make_debug_string):
	...this.
	(memento_of_new_rvalue_from_double::make_debug_string):
	Convert to...
	(memento_of_new_rvalue_from_const <double>::make_debug_string):
	...this.
	(memento_of_new_rvalue_from_ptr::make_debug_string)
	Convert to...
	(memento_of_new_rvalue_from_const <void *>::make_debug_string):
	...this.
	(memento_of_new_rvalue_from_const <long>::make_debug_string):
	New function.
	* jit-recording.h: Within namespace gcc::jit::recording...
	(context::new_rvalue_from_int): Eliminate.
	(context::new_rvalue_from_double): Likewise.
	(context::new_rvalue_from_ptr): Likewise, all in favor of...
	(context::new_rvalue_from_const <HOST_TYPE>): New family of
	methods.
	(class memento_of_new_rvalue_from_int): Eliminate.
	(class memento_of_new_rvalue_from_double): Likewise.
	(class memento_of_new_rvalue_from_ptr): Likewise.
	(class memento_of_new_rvalue_from_const <HOST_TYPE>): New family
	of rvalue subclasses.
	* libgccjit++.h (gccjit::context::new_rvalue): New overload, for
	"long".
	* libgccjit.c (gcc_jit_context_new_rvalue_from_int): Update for
	rewriting of recording::context::new_rvalue_from_int to
	recording::context::new_rvalue_from_const <int>.
	(gcc_jit_context_new_rvalue_from_long): New API entrypoint.
	(gcc_jit_context_new_rvalue_from_double): Update for
	rewriting of recording::context::new_rvalue_from_double to
	recording::context::new_rvalue_from_const <double>.
	(gcc_jit_context_new_rvalue_from_ptr): Update for
	rewriting of recording::context::new_rvalue_from_ptr to
	recording::context::new_rvalue_from_const <void *>.
	* libgccjit.h (gcc_jit_context_new_rvalue_from_long): New API
	entrypoint.
	* libgccjit.map (gcc_jit_context_new_rvalue_from_long): Likewise.

gcc/testsuite/ChangeLog:
	* jit.dg/all-non-failing-tests.h: Add test-constants.c.
	* jit.dg/test-combination.c (create_code): Likewise.
	(verify_code): Likewise.
	* jit.dg/test-constants.c: New test case.
	* jit.dg/test-threads.c: Add test-constants.c.
---
 gcc/jit/docs/cp/topics/expressions.rst       |  11 +-
 gcc/jit/docs/topics/expressions.rst          |  12 +-
 gcc/jit/jit-playback.c                       |  75 ++++--
 gcc/jit/jit-playback.h                       |  13 +-
 gcc/jit/jit-recording.c                      | 151 +++++-------
 gcc/jit/jit-recording.h                      |  85 +++----
 gcc/jit/libgccjit++.h                        |  12 +
 gcc/jit/libgccjit.c                          |  24 +-
 gcc/jit/libgccjit.h                          |   5 +
 gcc/jit/libgccjit.map                        |   1 +
 gcc/testsuite/jit.dg/all-non-failing-tests.h |   7 +
 gcc/testsuite/jit.dg/test-combination.c      |   2 +
 gcc/testsuite/jit.dg/test-constants.c        | 339 +++++++++++++++++++++++++++
 gcc/testsuite/jit.dg/test-threads.c          |   3 +
 14 files changed, 562 insertions(+), 178 deletions(-)
 create mode 100644 gcc/testsuite/jit.dg/test-constants.c

diff --git a/gcc/jit/docs/cp/topics/expressions.rst b/gcc/jit/docs/cp/topics/expressions.rst
index 6d9e53b..b58eeff 100644
--- a/gcc/jit/docs/cp/topics/expressions.rst
+++ b/gcc/jit/docs/cp/topics/expressions.rst
@@ -57,7 +57,14 @@ Simple expressions
                                            int value) const
 
    Given a numeric type (integer or floating point), build an rvalue for
-   the given constant ``int`` value.
+   the given constant :c:type:`int` value.
+
+.. function:: gccjit::rvalue \
+              gccjit::context::new_rvalue (gccjit::type numeric_type, \
+                                           long value) const
+
+   Given a numeric type (integer or floating point), build an rvalue for
+   the given constant :c:type:`long` value.
 
 .. function::  gccjit::rvalue \
                gccjit::context::zero (gccjit::type numeric_type) const
@@ -84,7 +91,7 @@ Simple expressions
                                             double value) const
 
    Given a numeric type (integer or floating point), build an rvalue for
-   the given constant value.
+   the given constant :c:type:`double` value.
 
 .. function:: gccjit::rvalue \
               gccjit::context::new_rvalue (gccjit::type pointer_type, \
diff --git a/gcc/jit/docs/topics/expressions.rst b/gcc/jit/docs/topics/expressions.rst
index 72a1085..13a28e8 100644
--- a/gcc/jit/docs/topics/expressions.rst
+++ b/gcc/jit/docs/topics/expressions.rst
@@ -60,7 +60,15 @@ Simple expressions
                                                    int value)
 
    Given a numeric type (integer or floating point), build an rvalue for
-   the given constant value.
+   the given constant :c:type:`int` value.
+
+.. function:: gcc_jit_rvalue *\
+              gcc_jit_context_new_rvalue_from_long (gcc_jit_context *ctxt, \
+                                                    gcc_jit_type *numeric_type, \
+                                                    long value)
+
+   Given a numeric type (integer or floating point), build an rvalue for
+   the given constant :c:type:`long` value.
 
 .. function::  gcc_jit_rvalue *gcc_jit_context_zero (gcc_jit_context *ctxt, \
                                                      gcc_jit_type *numeric_type)
@@ -88,7 +96,7 @@ Simple expressions
                                                        double value)
 
    Given a numeric type (integer or floating point), build an rvalue for
-   the given constant value.
+   the given constant :c:type:`double` value.
 
 .. function:: gcc_jit_rvalue *\
               gcc_jit_context_new_rvalue_from_ptr (gcc_jit_context *ctxt, \
diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c
index 4019778..9c3bc17 100644
--- a/gcc/jit/jit-playback.c
+++ b/gcc/jit/jit-playback.c
@@ -486,12 +486,25 @@ new_global (location *loc,
   return new lvalue (this, inner);
 }
 
-/* Construct a playback::rvalue instance (wrapping a tree).  */
+/* Implementation of the various
+      gcc::jit::playback::context::new_rvalue_from_const <HOST_TYPE>
+   methods.
+   Each of these constructs a playback::rvalue instance (wrapping a tree).
 
-playback::rvalue *
-playback::context::
-new_rvalue_from_int (type *type,
-		     int value)
+   These specializations are required to be in the same namespace
+   as the template, hence we now have to enter the gcc::jit::playback
+   namespace.  */
+
+namespace playback
+{
+
+/* Specialization of making an rvalue from a const, for host <int>.  */
+
+template <>
+rvalue *
+context::
+new_rvalue_from_const <int> (type *type,
+			     int value)
 {
   // FIXME: type-checking, or coercion?
   tree inner_type = type->as_tree ();
@@ -509,12 +522,37 @@ new_rvalue_from_int (type *type,
     }
 }
 
-/* Construct a playback::rvalue instance (wrapping a tree).  */
+/* Specialization of making an rvalue from a const, for host <long>.  */
 
-playback::rvalue *
-playback::context::
-new_rvalue_from_double (type *type,
-			double value)
+template <>
+rvalue *
+context::
+new_rvalue_from_const <long> (type *type,
+			      long value)
+{
+  // FIXME: type-checking, or coercion?
+  tree inner_type = type->as_tree ();
+  if (INTEGRAL_TYPE_P (inner_type))
+    {
+      tree inner = build_int_cst (inner_type, value);
+      return new rvalue (this, inner);
+    }
+  else
+    {
+      REAL_VALUE_TYPE real_value;
+      real_from_integer (&real_value, VOIDmode, value, SIGNED);
+      tree inner = build_real (inner_type, real_value);
+      return new rvalue (this, inner);
+    }
+}
+
+/* Specialization of making an rvalue from a const, for host <double>.  */
+
+template <>
+rvalue *
+context::
+new_rvalue_from_const <double> (type *type,
+				double value)
 {
   // FIXME: type-checking, or coercion?
   tree inner_type = type->as_tree ();
@@ -539,12 +577,13 @@ new_rvalue_from_double (type *type,
   return new rvalue (this, inner);
 }
 
-/* Construct a playback::rvalue instance (wrapping a tree).  */
+/* Specialization of making an rvalue from a const, for host <void *>.  */
 
-playback::rvalue *
-playback::context::
-new_rvalue_from_ptr (type *type,
-		     void *value)
+template <>
+rvalue *
+context::
+new_rvalue_from_const <void *> (type *type,
+				void *value)
 {
   tree inner_type = type->as_tree ();
   /* FIXME: how to ensure we have a wide enough type?  */
@@ -552,6 +591,12 @@ new_rvalue_from_ptr (type *type,
   return new rvalue (this, inner);
 }
 
+/* We're done implementing the specializations of
+      gcc::jit::playback::context::new_rvalue_from_const <T>
+   so we can exit the gcc::jit::playback namespace.  */
+
+} // namespace playback
+
 /* Construct a playback::rvalue instance (wrapping a tree).  */
 
 playback::rvalue *
diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
index 3a03b3a..07d030e 100644
--- a/gcc/jit/jit-playback.h
+++ b/gcc/jit/jit-playback.h
@@ -93,17 +93,10 @@ public:
 	      type *type,
 	      const char *name);
 
+  template <typename HOST_TYPE>
   rvalue *
-  new_rvalue_from_int (type *type,
-		       int value);
-
-  rvalue *
-  new_rvalue_from_double (type *type,
-			  double value);
-
-  rvalue *
-  new_rvalue_from_ptr (type *type,
-		       void *value);
+  new_rvalue_from_const (type *type,
+			 HOST_TYPE value);
 
   rvalue *
   new_string_literal (const char *value);
diff --git a/gcc/jit/jit-recording.c b/gcc/jit/jit-recording.c
index a9ff300..63dab38 100644
--- a/gcc/jit/jit-recording.c
+++ b/gcc/jit/jit-recording.c
@@ -647,54 +647,6 @@ recording::context::new_global (recording::location *loc,
   return result;
 }
 
-/* Create a recording::memento_of_new_rvalue_from_int instance and add
-   it to this context's list of mementos.
-
-   Implements the post-error-checking part of
-   gcc_jit_context_new_rvalue_from_int.  */
-
-recording::rvalue *
-recording::context::new_rvalue_from_int (recording::type *type,
-					 int value)
-{
-  recording::rvalue *result =
-    new memento_of_new_rvalue_from_int (this, NULL, type, value);
-  record (result);
-  return result;
-}
-
-/* Create a recording::memento_of_new_rvalue_from_double instance and
-   add it to this context's list of mementos.
-
-   Implements the post-error-checking part of
-   gcc_jit_context_new_rvalue_from_double.  */
-
-recording::rvalue *
-recording::context::new_rvalue_from_double (recording::type *type,
-					    double value)
-{
-  recording::rvalue *result =
-    new memento_of_new_rvalue_from_double (this, NULL, type, value);
-  record (result);
-  return result;
-}
-
-/* Create a recording::memento_of_new_rvalue_from_ptr instance and add
-   it to this context's list of mementos.
-
-   Implements the post-error-checking part of
-   gcc_jit_context_new_rvalue_from_ptr.  */
-
-recording::rvalue *
-recording::context::new_rvalue_from_ptr (recording::type *type,
-					 void *value)
-{
-  recording::rvalue *result =
-    new memento_of_new_rvalue_from_ptr (this, NULL, type, value);
-  record (result);
-  return result;
-}
-
 /* Create a recording::memento_of_new_string_literal instance and add it
    to this context's list of mementos.
 
@@ -2702,26 +2654,51 @@ recording::global::replay_into (replayer *r)
 				   playback_string (m_name)));
 }
 
-/* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_int.  */
+/* The implementation of the various const-handling classes:
+   gcc::jit::recording::memento_of_new_rvalue_from_const <HOST_TYPE>.  */
 
-/* Implementation of pure virtual hook recording::memento::replay_into
-   for recording::memento_of_new_rvalue_from_int.  */
+/* Explicit specialization of the various mementos we're interested in.  */
+template class recording::memento_of_new_rvalue_from_const <int>;
+template class recording::memento_of_new_rvalue_from_const <long>;
+template class recording::memento_of_new_rvalue_from_const <double>;
+template class recording::memento_of_new_rvalue_from_const <void *>;
+
+/* Implementation of the pure virtual hook recording::memento::replay_into
+   for recording::memento_of_new_rvalue_from_const <HOST_TYPE>.  */
 
+template <typename HOST_TYPE>
 void
-recording::memento_of_new_rvalue_from_int::replay_into (replayer *r)
+recording::
+memento_of_new_rvalue_from_const <HOST_TYPE>::replay_into (replayer *r)
 {
-  set_playback_obj (r->new_rvalue_from_int (m_type->playback_type (),
-					    m_value));
+    set_playback_obj
+      (r->new_rvalue_from_const <HOST_TYPE> (m_type->playback_type (),
+					     m_value));
 }
 
-/* Implementation of recording::memento::make_debug_string for
-   rvalue_from_int, rendering it as
-     (TYPE)LITERAL
+/* The make_debug_string method varies between the various
+   memento_of_new_rvalue_from_const <HOST_TYPE> classes, so we explicitly
+   write specializations of it.
+
+   I (dmalcolm) find the code to be clearer if the "recording" vs "playback"
+   namespaces are written out explicitly, which is why most of this file
+   doesn't abbreviate things by entering the "recording" namespace.
+
+   However, these specializations are required to be in the same namespace
+   as the template, hence we now have to enter the gcc::jit::recording
+   namespace.  */
+
+namespace recording
+{
+
+/* The make_debug_string specialization for <int>, which renders it as
+     (TARGET_TYPE)LITERAL
    e.g.
      "(int)42".  */
 
-recording::string *
-recording::memento_of_new_rvalue_from_int::make_debug_string ()
+template <>
+string *
+memento_of_new_rvalue_from_const <int>::make_debug_string ()
 {
   return string::from_printf (m_ctxt,
 			      "(%s)%i",
@@ -2729,26 +2706,29 @@ recording::memento_of_new_rvalue_from_int::make_debug_string ()
 			      m_value);
 }
 
-/* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_double.  */
-
-/* Implementation of pure virtual hook recording::memento::replay_into
-   for recording::memento_of_new_rvalue_from_double.  */
+/* The make_debug_string specialization for <long>, rendering it as
+     (TARGET_TYPE)LITERAL
+   e.g.
+     "(long)42".  */
 
-void
-recording::memento_of_new_rvalue_from_double::replay_into (replayer *r)
+template <>
+string *
+memento_of_new_rvalue_from_const <long>::make_debug_string ()
 {
-  set_playback_obj (r->new_rvalue_from_double (m_type->playback_type (),
-					       m_value));
+  return string::from_printf (m_ctxt,
+			      "(%s)%li",
+			      m_type->get_debug_string (),
+			      m_value);
 }
 
-/* Implementation of recording::memento::make_debug_string for
-   rvalue_from_double, rendering it as
-     (TYPE)LITERAL
+/* The make_debug_string specialization for <double>, rendering it as
+     (TARGET_TYPE)LITERAL
    e.g.
      "(float)42.0".  */
 
-recording::string *
-recording::memento_of_new_rvalue_from_double::make_debug_string ()
+template <>
+string *
+memento_of_new_rvalue_from_const <double>::make_debug_string ()
 {
   return string::from_printf (m_ctxt,
 			      "(%s)%f",
@@ -2756,29 +2736,17 @@ recording::memento_of_new_rvalue_from_double::make_debug_string ()
 			      m_value);
 }
 
-/* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_ptr.  */
-
-/* Implementation of pure virtual hook recording::memento::replay_into
-   for recording::memento_of_new_rvalue_from_ptr.  */
-
-void
-recording::memento_of_new_rvalue_from_ptr::replay_into (replayer *r)
-{
-  set_playback_obj (r->new_rvalue_from_ptr (m_type->playback_type (),
-					    m_value));
-}
-
-/* Implementation of recording::memento::make_debug_string for
-   rvalue_from_ptr, rendering it as
-     (TYPE)HEX
+/* The make_debug_string specialization for <void *>, rendering it as
+     (TARGET_TYPE)HEX
    e.g.
      "(int *)0xdeadbeef"
 
    Zero is rendered as NULL e.g.
      "(int *)NULL".  */
 
-recording::string *
-recording::memento_of_new_rvalue_from_ptr::make_debug_string ()
+template <>
+string *
+memento_of_new_rvalue_from_const <void *>::make_debug_string ()
 {
   if (m_value != NULL)
     return string::from_printf (m_ctxt,
@@ -2790,6 +2758,11 @@ recording::memento_of_new_rvalue_from_ptr::make_debug_string ()
 				m_type->get_debug_string ());
 }
 
+/* We're done specializing make_debug_string, so we can exit the
+   gcc::jit::recording namespace.  */
+
+} // namespace recording
+
 /* The implementation of class gcc::jit::recording::memento_of_new_string_literal.  */
 
 /* Implementation of pure virtual hook recording::memento::replay_into
diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h
index 9417993..8d15487 100644
--- a/gcc/jit/jit-recording.h
+++ b/gcc/jit/jit-recording.h
@@ -135,17 +135,10 @@ public:
 	      type *type,
 	      const char *name);
 
+  template <typename HOST_TYPE>
   rvalue *
-  new_rvalue_from_int (type *numeric_type,
-		       int value);
-
-  rvalue *
-  new_rvalue_from_double (type *numeric_type,
-			  double value);
-
-  rvalue *
-  new_rvalue_from_ptr (type *pointer_type,
-		       void *value);
+  new_rvalue_from_const (type *type,
+			 HOST_TYPE value);
 
   rvalue *
   new_string_literal (const char *value);
@@ -1073,14 +1066,15 @@ private:
   string *m_name;
 };
 
-class memento_of_new_rvalue_from_int : public rvalue
+template <typename HOST_TYPE>
+class memento_of_new_rvalue_from_const : public rvalue
 {
 public:
-  memento_of_new_rvalue_from_int (context *ctxt,
-				  location *loc,
-				  type *numeric_type,
-				  int value)
-  : rvalue (ctxt, loc, numeric_type),
+  memento_of_new_rvalue_from_const (context *ctxt,
+				    location *loc,
+				    type *type,
+				    HOST_TYPE value)
+  : rvalue (ctxt, loc, type),
     m_value (value) {}
 
   void replay_into (replayer *r);
@@ -1089,47 +1083,7 @@ private:
   string * make_debug_string ();
 
 private:
-  int m_value;
-};
-
-class memento_of_new_rvalue_from_double : public rvalue
-{
-public:
-  memento_of_new_rvalue_from_double (context *ctxt,
-				     location *loc,
-				     type *numeric_type,
-				     double value)
-  : rvalue (ctxt, loc, numeric_type),
-    m_value (value)
-  {}
-
-  void replay_into (replayer *);
-
-private:
-  string * make_debug_string ();
-
-private:
-  double m_value;
-};
-
-class memento_of_new_rvalue_from_ptr : public rvalue
-{
-public:
-  memento_of_new_rvalue_from_ptr (context *ctxt,
-				  location *loc,
-				  type *pointer_type,
-				  void *value)
-  : rvalue (ctxt, loc, pointer_type),
-    m_value (value)
-  {}
-
-  void replay_into (replayer *);
-
-private:
-  string * make_debug_string ();
-
-private:
-  void *m_value;
+  HOST_TYPE m_value;
 };
 
 class memento_of_new_string_literal : public rvalue
@@ -1605,6 +1559,23 @@ private:
 
 } // namespace gcc::jit::recording
 
+/* Create a recording::memento_of_new_rvalue_from_const instance and add
+   it to this context's list of mementos.
+
+   Implements the post-error-checking part of
+   gcc_jit_context_new_rvalue_from_{int|long|double|ptr}.  */
+
+template <typename HOST_TYPE>
+recording::rvalue *
+recording::context::new_rvalue_from_const (recording::type *type,
+					   HOST_TYPE value)
+{
+  recording::rvalue *result =
+    new memento_of_new_rvalue_from_const <HOST_TYPE> (this, NULL, type, value);
+  record (result);
+  return result;
+}
+
 } // namespace gcc::jit
 
 } // namespace gcc
diff --git a/gcc/jit/libgccjit++.h b/gcc/jit/libgccjit++.h
index 600219c..84144e5 100644
--- a/gcc/jit/libgccjit++.h
+++ b/gcc/jit/libgccjit++.h
@@ -161,6 +161,8 @@ namespace gccjit
 
     rvalue new_rvalue (type numeric_type,
 		       int value) const;
+    rvalue new_rvalue (type numeric_type,
+		       long value) const;
     rvalue zero (type numeric_type) const;
     rvalue one (type numeric_type) const;
     rvalue new_rvalue (type numeric_type,
@@ -726,6 +728,16 @@ context::new_rvalue (type numeric_type,
 }
 
 inline rvalue
+context::new_rvalue (type numeric_type,
+		     long value) const
+{
+  return rvalue (
+    gcc_jit_context_new_rvalue_from_long (m_inner_ctxt,
+					  numeric_type.get_inner_type (),
+					  value));
+}
+
+inline rvalue
 context::zero (type numeric_type) const
 {
   return rvalue (gcc_jit_context_zero (m_inner_ctxt,
diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c
index 34f201e..62d3edf 100644
--- a/gcc/jit/libgccjit.c
+++ b/gcc/jit/libgccjit.c
@@ -1080,7 +1080,23 @@ gcc_jit_context_new_rvalue_from_int (gcc_jit_context *ctxt,
   JIT_LOG_FUNC (ctxt->get_logger ());
   RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);
 
-  return (gcc_jit_rvalue *)ctxt->new_rvalue_from_int (numeric_type, value);
+  return ((gcc_jit_rvalue *)ctxt
+	  ->new_rvalue_from_const <int> (numeric_type, value));
+}
+
+/* FIXME. */
+
+gcc_jit_rvalue *
+gcc_jit_context_new_rvalue_from_long (gcc_jit_context *ctxt,
+				      gcc_jit_type *numeric_type,
+				      long value)
+{
+  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
+  JIT_LOG_FUNC (ctxt->get_logger ());
+  RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);
+
+  return ((gcc_jit_rvalue *)ctxt
+	  ->new_rvalue_from_const <long> (numeric_type, value));
 }
 
 /* Public entrypoint.  See description in libgccjit.h.
@@ -1132,7 +1148,8 @@ gcc_jit_context_new_rvalue_from_double (gcc_jit_context *ctxt,
   JIT_LOG_FUNC (ctxt->get_logger ());
   RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);
 
-  return (gcc_jit_rvalue *)ctxt->new_rvalue_from_double (numeric_type, value);
+  return ((gcc_jit_rvalue *)ctxt
+	  ->new_rvalue_from_const <double> (numeric_type, value));
 }
 
 /* Public entrypoint.  See description in libgccjit.h.
@@ -1155,7 +1172,8 @@ gcc_jit_context_new_rvalue_from_ptr (gcc_jit_context *ctxt,
     "not a pointer type (type: %s)",
     pointer_type->get_debug_string ());
 
-  return (gcc_jit_rvalue *)ctxt->new_rvalue_from_ptr (pointer_type, value);
+  return ((gcc_jit_rvalue *)ctxt
+	  ->new_rvalue_from_const <void *> (pointer_type, value));
 }
 
 /* Public entrypoint.  See description in libgccjit.h.
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index 70f26ba..92eed37 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -633,6 +633,11 @@ gcc_jit_context_new_rvalue_from_int (gcc_jit_context *ctxt,
 				     int value);
 
 extern gcc_jit_rvalue *
+gcc_jit_context_new_rvalue_from_long (gcc_jit_context *ctxt,
+				      gcc_jit_type *numeric_type,
+				      long value);
+
+extern gcc_jit_rvalue *
 gcc_jit_context_zero (gcc_jit_context *ctxt,
 		      gcc_jit_type *numeric_type);
 
diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map
index dc2fa6f..bc6eb1a 100644
--- a/gcc/jit/libgccjit.map
+++ b/gcc/jit/libgccjit.map
@@ -56,6 +56,7 @@
     gcc_jit_context_new_param;
     gcc_jit_context_new_rvalue_from_double;
     gcc_jit_context_new_rvalue_from_int;
+    gcc_jit_context_new_rvalue_from_long;
     gcc_jit_context_new_rvalue_from_ptr;
     gcc_jit_context_new_string_literal;
     gcc_jit_context_new_struct_type;
diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h
index beb3d13..14211af 100644
--- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
+++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
@@ -57,6 +57,13 @@
 #undef create_code
 #undef verify_code
 
+/* test-constants.c */
+#define create_code create_code_constants
+#define verify_code verify_code_constants
+#include "test-constants.c"
+#undef create_code
+#undef verify_code
+
 /* test-dot-product.c */
 #define create_code create_code_dot_product
 #define verify_code verify_code_dot_product
diff --git a/gcc/testsuite/jit.dg/test-combination.c b/gcc/testsuite/jit.dg/test-combination.c
index e99f4d0..5131613 100644
--- a/gcc/testsuite/jit.dg/test-combination.c
+++ b/gcc/testsuite/jit.dg/test-combination.c
@@ -22,6 +22,7 @@ create_code (gcc_jit_context *ctxt, void * user_data)
   create_code_arrays (ctxt, user_data);
   create_code_calling_external_function (ctxt, user_data);
   create_code_calling_function_ptr (ctxt, user_data);
+  create_code_constants (ctxt, user_data);
   create_code_dot_product (ctxt, user_data);
   create_code_expressions (ctxt, user_data);
   create_code_factorial (ctxt, user_data);
@@ -50,6 +51,7 @@ verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
   verify_code_arrays (ctxt, result);
   verify_code_calling_external_function (ctxt, result);
   verify_code_calling_function_ptr (ctxt, result);
+  verify_code_constants (ctxt, result);
   verify_code_dot_product (ctxt, result);
   verify_code_expressions (ctxt, result);
   verify_code_factorial (ctxt, result);
diff --git a/gcc/testsuite/jit.dg/test-constants.c b/gcc/testsuite/jit.dg/test-constants.c
new file mode 100644
index 0000000..a509249
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-constants.c
@@ -0,0 +1,339 @@
+#include <limits.h>
+#include <float.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+static void
+make_test_of_constant (gcc_jit_context *ctxt,
+                       gcc_jit_type *type,
+                       gcc_jit_rvalue *rvalue,
+                       const char *funcname)
+{
+  /* Make a test function of the form:
+       T funcname (void)
+       {
+	  return VALUE;
+       }
+     and return a debug dump of VALUE so that
+     the caller can sanity-check the debug dump implementation.
+  */
+  gcc_jit_function *test_fn =
+    gcc_jit_context_new_function (ctxt, NULL,
+				  GCC_JIT_FUNCTION_EXPORTED,
+				  type,
+				  funcname,
+				  0, NULL,
+				  0);
+  gcc_jit_block *initial = gcc_jit_function_new_block (test_fn, "initial");
+  gcc_jit_block_end_with_return (initial, NULL, rvalue);
+}
+
+/**********************************************************************
+ Tests of gcc_jit_context_new_rvalue_from_int.
+ **********************************************************************/
+
+static const char *
+make_test_of_int_constant (gcc_jit_context *ctxt,
+			   gcc_jit_type *type,
+			   int value,
+			   const char *funcname)
+{
+  /* Make a test function of the form:
+       int funcname (void)
+       {
+	  return VALUE;
+       }
+     and return a debug dump of VALUE so that
+     the caller can sanity-check the debug dump implementation.
+  */
+  gcc_jit_rvalue *rvalue =
+    gcc_jit_context_new_rvalue_from_int (ctxt, type, value);
+  make_test_of_constant (ctxt, type, rvalue, funcname);
+  return gcc_jit_object_get_debug_string (
+    gcc_jit_rvalue_as_object (rvalue));
+}
+
+static void
+make_tests_of_int_constants (gcc_jit_context *ctxt)
+{
+  gcc_jit_type *int_type =
+    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+
+  CHECK_STRING_VALUE (
+    make_test_of_int_constant (ctxt,
+			       int_type,
+			       0,
+			       "test_int_constant_0"),
+    "(int)0");
+  make_test_of_int_constant (ctxt,
+                             int_type,
+                             INT_MAX,
+                             "test_int_constant_INT_MAX");
+  make_test_of_int_constant (ctxt,
+                             int_type,
+                             INT_MIN,
+                             "test_int_constant_INT_MIN");
+}
+
+static void
+verify_int_constants (gcc_jit_result *result)
+{
+  typedef int (*test_fn) (void);
+
+  test_fn test_int_constant_0 =
+    (test_fn)gcc_jit_result_get_code (result,
+				      "test_int_constant_0");
+  CHECK_NON_NULL (test_int_constant_0);
+  CHECK_VALUE (test_int_constant_0 (), 0);
+
+  test_fn test_int_constant_INT_MAX =
+    (test_fn)gcc_jit_result_get_code (result,
+				      "test_int_constant_INT_MAX");
+  CHECK_NON_NULL (test_int_constant_INT_MAX);
+  CHECK_VALUE (test_int_constant_INT_MAX (), INT_MAX);
+
+  test_fn test_int_constant_INT_MIN =
+    (test_fn)gcc_jit_result_get_code (result,
+				      "test_int_constant_INT_MIN");
+  CHECK_NON_NULL (test_int_constant_INT_MIN);
+  CHECK_VALUE (test_int_constant_INT_MIN (), INT_MIN);
+}
+
+/**********************************************************************
+ Tests of gcc_jit_context_new_rvalue_from_long.
+ **********************************************************************/
+
+static const char *
+make_test_of_long_constant (gcc_jit_context *ctxt,
+			   gcc_jit_type *type,
+			   long value,
+			   const char *funcname)
+{
+  /* Make a test function of the form:
+       long funcname (void)
+       {
+	  return VALUE;
+       }
+     and return a debug dump of VALUE so that
+     the caller can sanity-check the debug dump implementation.
+  */
+  gcc_jit_rvalue *rvalue =
+    gcc_jit_context_new_rvalue_from_long (ctxt, type, value);
+  make_test_of_constant (ctxt, type, rvalue, funcname);
+  return gcc_jit_object_get_debug_string (
+    gcc_jit_rvalue_as_object (rvalue));
+}
+
+static void
+make_tests_of_long_constants (gcc_jit_context *ctxt)
+{
+  gcc_jit_type *long_type =
+    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_LONG);
+
+  CHECK_STRING_VALUE (
+    make_test_of_long_constant (ctxt,
+			       long_type,
+			       0,
+			       "test_long_constant_0"),
+    "(long)0");
+  make_test_of_long_constant (ctxt,
+                             long_type,
+                             LONG_MAX,
+                             "test_long_constant_LONG_MAX");
+  make_test_of_long_constant (ctxt,
+                             long_type,
+                             LONG_MIN,
+                             "test_long_constant_LONG_MIN");
+}
+
+static void
+verify_long_constants (gcc_jit_result *result)
+{
+  typedef long (*test_fn) (void);
+
+  test_fn test_long_constant_0 =
+    (test_fn)gcc_jit_result_get_code (result,
+				      "test_long_constant_0");
+  CHECK_NON_NULL (test_long_constant_0);
+  CHECK_VALUE (test_long_constant_0 (), 0);
+
+  test_fn test_long_constant_LONG_MAX =
+    (test_fn)gcc_jit_result_get_code (result,
+				      "test_long_constant_LONG_MAX");
+  CHECK_NON_NULL (test_long_constant_LONG_MAX);
+  CHECK_VALUE (test_long_constant_LONG_MAX (), LONG_MAX);
+
+  test_fn test_long_constant_LONG_MIN =
+    (test_fn)gcc_jit_result_get_code (result,
+				      "test_long_constant_LONG_MIN");
+  CHECK_NON_NULL (test_long_constant_LONG_MIN);
+  CHECK_VALUE (test_long_constant_LONG_MIN (), LONG_MIN);
+}
+
+/**********************************************************************
+ Tests of gcc_jit_context_new_rvalue_from_double.
+ **********************************************************************/
+
+static const char *
+make_test_of_double_constant (gcc_jit_context *ctxt,
+			   gcc_jit_type *type,
+			   double value,
+			   const char *funcname)
+{
+  /* Make a test function of the form:
+       double funcname (void)
+       {
+	  return VALUE;
+       }
+     and return a debug dump of VALUE so that
+     the caller can sanity-check the debug dump implementation.
+  */
+  gcc_jit_rvalue *rvalue =
+    gcc_jit_context_new_rvalue_from_double (ctxt, type, value);
+  make_test_of_constant (ctxt, type, rvalue, funcname);
+  return gcc_jit_object_get_debug_string (
+    gcc_jit_rvalue_as_object (rvalue));
+}
+
+static void
+make_tests_of_double_constants (gcc_jit_context *ctxt)
+{
+  gcc_jit_type *double_type =
+    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE);
+
+  make_test_of_double_constant (ctxt,
+                                double_type,
+                                0.5,
+                                "test_double_constant_0_5");
+  make_test_of_double_constant (ctxt,
+                                double_type,
+                                1e100,
+                                "test_double_constant_1e100");
+  make_test_of_double_constant (ctxt,
+                                double_type,
+                                DBL_MIN,
+                                "test_double_constant_DBL_MIN");
+  make_test_of_double_constant (ctxt,
+                                double_type,
+                                DBL_MAX,
+                                "test_double_constant_DBL_MAX");
+}
+
+static void
+verify_double_constants (gcc_jit_result *result)
+{
+  typedef double (*test_fn) (void);
+
+  test_fn test_double_constant_0_5 =
+    (test_fn)gcc_jit_result_get_code (result,
+				      "test_double_constant_0_5");
+  CHECK_NON_NULL (test_double_constant_0_5);
+  CHECK_VALUE (test_double_constant_0_5 (), 0.5);
+
+  test_fn test_double_constant_1e100 =
+    (test_fn)gcc_jit_result_get_code (result,
+				      "test_double_constant_1e100");
+  CHECK_NON_NULL (test_double_constant_1e100);
+  CHECK_VALUE (test_double_constant_1e100 (), 1e100);
+
+  test_fn test_double_constant_DBL_MIN =
+    (test_fn)gcc_jit_result_get_code (result,
+				      "test_double_constant_DBL_MIN");
+  CHECK_NON_NULL (test_double_constant_DBL_MIN);
+  CHECK_VALUE (test_double_constant_DBL_MIN (), DBL_MIN);
+
+  test_fn test_double_constant_DBL_MAX =
+    (test_fn)gcc_jit_result_get_code (result,
+				      "test_double_constant_DBL_MAX");
+  CHECK_NON_NULL (test_double_constant_DBL_MAX);
+  CHECK_VALUE (test_double_constant_DBL_MAX (), DBL_MAX);
+}
+
+/**********************************************************************
+ Tests of gcc_jit_context_new_rvalue_from_ptr.
+ **********************************************************************/
+
+static const char *
+make_test_of_ptr_constant (gcc_jit_context *ctxt,
+			   gcc_jit_type *type,
+			   void *value,
+			   const char *funcname)
+{
+  /* Make a test function of the form:
+       void *funcname (void)
+       {
+	  return VALUE;
+       }
+     and return a debug dump of VALUE so that
+     the caller can sanity-check the debug dump implementation.
+  */
+  gcc_jit_rvalue *rvalue =
+    gcc_jit_context_new_rvalue_from_ptr (ctxt, type, value);
+  make_test_of_constant (ctxt, type, rvalue, funcname);
+  return gcc_jit_object_get_debug_string (
+    gcc_jit_rvalue_as_object (rvalue));
+}
+
+static void
+make_tests_of_ptr_constants (gcc_jit_context *ctxt)
+{
+  gcc_jit_type *ptr_type =
+    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID_PTR);
+
+  CHECK_STRING_VALUE (
+    make_test_of_ptr_constant (ctxt,
+			       ptr_type,
+			       0,
+			       "test_ptr_constant_0"),
+    "(void *)NULL");
+  CHECK_STRING_VALUE (
+    make_test_of_ptr_constant (ctxt,
+			       ptr_type,
+			       (void *)0xdeadbeef,
+			       "test_ptr_constant_0xdeadbeef"),
+    "(void *)0xdeadbeef");
+}
+
+static void
+verify_ptr_constants (gcc_jit_result *result)
+{
+  typedef void *(*test_fn) (void);
+
+  test_fn test_ptr_constant_0 =
+    (test_fn)gcc_jit_result_get_code (result,
+				      "test_ptr_constant_0");
+  CHECK_NON_NULL (test_ptr_constant_0);
+  CHECK_VALUE (test_ptr_constant_0 (), 0);
+
+  test_fn test_ptr_constant_0xdeadbeef =
+    (test_fn)gcc_jit_result_get_code (result,
+				      "test_ptr_constant_0xdeadbeef");
+  CHECK_NON_NULL (test_ptr_constant_0xdeadbeef);
+  CHECK_VALUE (test_ptr_constant_0xdeadbeef (), (void *)0xdeadbeef);
+}
+
+/**********************************************************************
+ Code for harness
+ **********************************************************************/
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+  make_tests_of_int_constants (ctxt);
+  make_tests_of_long_constants (ctxt);
+  make_tests_of_double_constants (ctxt);
+  make_tests_of_ptr_constants (ctxt);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+  CHECK_NON_NULL (result);
+
+  verify_int_constants (result);
+  verify_long_constants (result);
+  verify_double_constants (result);
+  verify_ptr_constants (result);
+}
diff --git a/gcc/testsuite/jit.dg/test-threads.c b/gcc/testsuite/jit.dg/test-threads.c
index cd5ef6a..13e414d 100644
--- a/gcc/testsuite/jit.dg/test-threads.c
+++ b/gcc/testsuite/jit.dg/test-threads.c
@@ -122,6 +122,9 @@ const struct testcase testcases[] = {
   {"calling_function_ptr",
    create_code_calling_function_ptr,
    verify_code_calling_function_ptr},
+  {"constants",
+   create_code_constants,
+   verify_code_constants},
   {"dot_product",
    create_code_dot_product,
    verify_code_dot_product},
-- 
1.8.5.3



More information about the Gcc-patches mailing list