From: Guillaume Gomez <[email protected]>

gcc/jit/ChangeLog:

        * jit-recording.cc: Add new `context::m_type_mementos` field
        * jit-recording.h: Add new `context::m_type_mementos` field
        * libgccjit++.h: Add new `rvalue::set_type` method
        * libgccjit.cc: Add new `gcc_jit_rvalue_set_type` function
        * libgccjit.h: Add new `gcc_jit_rvalue_set_type` function
        * libgccjit.map: Declare new `gcc_jit_rvalue_set_type` API

gcc/testsuite/ChangeLog:

        * jit.dg/test-using-global.c: Add test for `gcc_jit_rvalue_set_type`
---
 gcc/jit/jit-recording.cc                 | 77 +++++++++++++++++++-----
 gcc/jit/jit-recording.h                  | 25 ++++----
 gcc/jit/libgccjit++.h                    |  7 +++
 gcc/jit/libgccjit.cc                     | 14 +++++
 gcc/jit/libgccjit.h                      |  3 +
 gcc/jit/libgccjit.map                    |  5 ++
 gcc/testsuite/jit.dg/test-using-global.c | 10 ++-
 7 files changed, 115 insertions(+), 26 deletions(-)

diff --git a/gcc/jit/jit-recording.cc b/gcc/jit/jit-recording.cc
index 07c82cc1b4fd..038ca9547632 100644
--- a/gcc/jit/jit-recording.cc
+++ b/gcc/jit/jit-recording.cc
@@ -565,6 +565,7 @@ recording::context::context (context *parent_ctxt)
     m_last_error_str (NULL),
     m_owns_last_error_str (false),
     m_mementos (),
+    m_type_mementos (),
     m_compound_types (),
     m_globals (),
     m_functions (),
@@ -614,6 +615,10 @@ recording::context::~context ()
     {
       delete m;
     }
+  FOR_EACH_VEC_ELT (m_type_mementos, i, m)
+    {
+      delete m;
+    }
 
   for (i = 0; i < GCC_JIT_NUM_STR_OPTIONS; ++i)
     free (m_str_options[i]);
@@ -647,6 +652,14 @@ recording::context::record (memento *m)
   m_mementos.safe_push (m);
 }
 
+void
+recording::context::record_type (memento *m)
+{
+  gcc_assert (m);
+
+  m_type_mementos.safe_push (m);
+}
+
 /* Replay this context (and any parents) into the given replayer.  */
 
 void
@@ -677,6 +690,24 @@ recording::context::replay_into (replayer *r)
   if (r->errors_occurred ())
     return;
 
+  FOR_EACH_VEC_ELT (m_type_mementos, i, m)
+    {
+      /* Disabled low-level debugging, here if we need it: print what
+        we're replaying.
+        Note that the calls to get_debug_string might lead to more
+        mementos being created for the strings.
+        This can also be used to exercise the debug_string
+        machinery.  */
+      if (0)
+       printf ("context %p replaying (%p): %s\n",
+               (void *)this, (void *)m, m->get_debug_string ());
+
+      m->replay_into (r);
+
+      if (r->errors_occurred ())
+       return;
+    }
+
   /* Replay this context's saved operations into r.  */
   FOR_EACH_VEC_ELT (m_mementos, i, m)
     {
@@ -717,6 +748,11 @@ recording::context::disassociate_from_playback ()
   if (m_parent_ctxt)
     m_parent_ctxt->disassociate_from_playback ();
 
+  FOR_EACH_VEC_ELT (m_type_mementos, i, m)
+    {
+      m->set_playback_obj (NULL);
+    }
+
   FOR_EACH_VEC_ELT (m_mementos, i, m)
     {
       m->set_playback_obj (NULL);
@@ -757,6 +793,10 @@ recording::context::new_location (const char *filename,
                             line, column,
                             created_by_user);
   record (result);
+  if (created_by_user)
+    record_type (result);
+  else
+    record (result);
   return result;
 }
 
@@ -782,7 +822,7 @@ recording::context::get_type (enum gcc_jit_types kind)
       else
        {
          recording::type *result = new memento_of_get_type (this, kind);
-         record (result);
+         record_type (result);
          m_basic_types[kind] = result;
        }
     }
@@ -860,7 +900,7 @@ recording::context::new_array_type (recording::location 
*loc,
       }
   recording::type *result =
     new recording::array_type (this, loc, element_type, num_elements);
-  record (result);
+  record_type (result);
   return result;
 }
 
@@ -877,7 +917,7 @@ recording::context::new_field (recording::location *loc,
 {
   recording::field *result =
     new recording::field (this, loc, type, new_string (name));
-  record (result);
+  record_type (result);
   return result;
 }
 
@@ -895,7 +935,7 @@ recording::context::new_bitfield (recording::location *loc,
 {
   recording::field *result =
     new recording::bitfield (this, loc, type, width, new_string (name));
-  record (result);
+  record_type (result);
   return result;
 }
 
@@ -910,7 +950,7 @@ recording::context::new_struct_type (recording::location 
*loc,
                                     const char *name)
 {
   recording::struct_ *result = new struct_ (this, loc, new_string (name));
-  record (result);
+  record_type (result);
   m_compound_types.safe_push (result);
   return result;
 }
@@ -926,7 +966,7 @@ recording::context::new_union_type (recording::location 
*loc,
                                    const char *name)
 {
   recording::union_ *result = new union_ (this, loc, new_string (name));
-  record (result);
+  record_type (result);
   m_compound_types.safe_push (result);
   return result;
 }
@@ -950,7 +990,7 @@ recording::context::new_function_type (recording::type 
*return_type,
                         param_types,
                         is_variadic,
                         is_target_builtin);
-  record (fn_type);
+  record_type (fn_type);
   return fn_type;
 }
 
@@ -2208,6 +2248,8 @@ recording::context::dump_reproducer_to_file (const char 
*path)
 
       r.write ("  /* Replay of API calls for %s.  */\n",
               r.get_identifier (contexts[ctxt_idx]));
+      FOR_EACH_VEC_ELT (contexts[ctxt_idx]->m_type_mementos, i, m)
+       m->write_reproducer (r);
       FOR_EACH_VEC_ELT (contexts[ctxt_idx]->m_mementos, i, m)
        m->write_reproducer (r);
     }
@@ -2512,7 +2554,7 @@ recording::type::get_pointer ()
   if (!m_pointer_to_this_type)
     {
       m_pointer_to_this_type = new memento_of_get_pointer (this);
-      m_ctxt->record (m_pointer_to_this_type);
+      m_ctxt->record_type (m_pointer_to_this_type);
     }
   return m_pointer_to_this_type;
 }
@@ -2526,7 +2568,7 @@ recording::type *
 recording::type::get_const ()
 {
   recording::type *result = new memento_of_get_const (this);
-  m_ctxt->record (result);
+  m_ctxt->record_type (result);
   return result;
 }
 
@@ -2539,7 +2581,7 @@ recording::type *
 recording::type::get_restrict ()
 {
   recording::type *result = new memento_of_get_restrict (this);
-  m_ctxt->record (result);
+  m_ctxt->record_type (result);
   return result;
 }
 
@@ -2552,7 +2594,7 @@ recording::type *
 recording::type::get_volatile ()
 {
   recording::type *result = new memento_of_get_volatile (this);
-  m_ctxt->record (result);
+  m_ctxt->record_type (result);
   return result;
 }
 
@@ -2566,7 +2608,7 @@ recording::type::get_aligned (size_t alignment_in_bytes)
 {
   recording::type *result
     = new memento_of_get_aligned (this, alignment_in_bytes);
-  m_ctxt->record (result);
+  m_ctxt->record_type (result);
   return result;
 }
 
@@ -2580,7 +2622,7 @@ recording::type::get_vector (size_t num_units)
 {
   recording::type *result
     = new vector_type (this, num_units);
-  m_ctxt->record (result);
+  m_ctxt->record_type (result);
   return result;
 }
 
@@ -3818,7 +3860,7 @@ recording::compound_type::set_fields (location *loc,
   gcc_assert (m_fields == NULL);
 
   m_fields = new fields (this, num_fields, field_array);
-  m_ctxt->record (m_fields);
+  m_ctxt->record_type (m_fields);
 }
 
 /* Implementation of pure virtual hook recording::type::dereference for
@@ -4063,6 +4105,13 @@ recording::rvalue::access_field (recording::location 
*loc,
   return result;
 }
 
+void
+recording::rvalue::set_type (type *new_type)
+{
+  gcc_assert (new_type);
+  m_type = new_type;
+}
+
 /* Create a recording::dereference_field_rvalue instance and add it to
    the rvalue's context's list of mementos.
 
diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h
index 2a5f23a058a1..16a55b1233bc 100644
--- a/gcc/jit/jit-recording.h
+++ b/gcc/jit/jit-recording.h
@@ -85,6 +85,7 @@ public:
   get_builtins_manager ();
 
   void record (memento *m);
+  void record_type (memento *m);
   void replay_into (replayer *r);
   void disassociate_from_playback ();
 
@@ -427,6 +428,7 @@ private:
 
   /* Recorded API usage.  */
   auto_vec<memento *> m_mementos;
+  auto_vec<memento *> m_type_mementos;
 
   /* Specific recordings, for use by dump_to_file.  */
   auto_vec<compound_type *> m_compound_types;
@@ -774,7 +776,7 @@ public:
   type* copy (context* ctxt) final override
   {
     type* result = new memento_of_get_pointer (m_other_type->copy (ctxt));
-    ctxt->record (result);
+    ctxt->record_type (result);
     return result;
   }
 
@@ -844,7 +846,7 @@ public:
   type* copy (context* ctxt) final override
   {
     type* result = new memento_of_get_const (m_other_type->copy (ctxt));
-    ctxt->record (result);
+    ctxt->record_type (result);
     return result;
   }
 
@@ -884,7 +886,7 @@ public:
   type* copy (context* ctxt) final override
   {
     type* result = new memento_of_get_volatile (m_other_type->copy (ctxt));
-    ctxt->record (result);
+    ctxt->record_type (result);
     return result;
   }
 
@@ -917,7 +919,7 @@ public:
   type* copy (context* ctxt) final override
   {
     type* result = new memento_of_get_restrict (m_other_type->copy (ctxt));
-    ctxt->record (result);
+    ctxt->record_type (result);
     return result;
   }
 
@@ -958,7 +960,7 @@ public:
   {
     type* result = new memento_of_get_aligned (m_other_type->copy (ctxt),
                                               m_alignment_in_bytes);
-    ctxt->record (result);
+    ctxt->record_type (result);
     return result;
   }
 
@@ -1007,7 +1009,7 @@ public:
   type* copy (context* ctxt) final override
   {
     type* result = new vector_type (m_other_type->copy (ctxt), m_num_units);
-    ctxt->record (result);
+    ctxt->record_type (result);
     return result;
   }
 
@@ -1069,7 +1071,7 @@ class array_type : public type
   {
     type* result = new array_type (ctxt, m_loc, m_element_type->copy (ctxt),
                                   m_num_elements);
-    ctxt->record (result);
+    ctxt->record_type (result);
     return result;
   }
 
@@ -1119,7 +1121,7 @@ public:
                                      m_param_types.length (),
                                      new_params.address (),
                                      m_is_variadic, m_is_target_builtin);
-    ctxt->record (result);
+    ctxt->record_type (result);
     return result;
   }
 
@@ -1273,7 +1275,7 @@ public:
   type* copy (context* ctxt) final override
   {
     type* result = new struct_ (ctxt, m_loc, m_name);
-    ctxt->record (result);
+    ctxt->record_type (result);
     return result;
   }
 
@@ -1327,7 +1329,7 @@ public:
   type* copy (context* ctxt) final override
   {
     type* result = new union_ (ctxt, m_loc, m_name);
-    ctxt->record (result);
+    ctxt->record_type (result);
     return result;
   }
 
@@ -1393,6 +1395,7 @@ public:
      Implements the post-error-checking part of
      gcc_jit_rvalue_get_type.  */
   type * get_type () const { return m_type; }
+  void set_type (type * new_type);
 
   playback::rvalue *
   playback_rvalue () const
@@ -2057,7 +2060,7 @@ public:
       else
        inner_type = element_type;
       m_type = new vector_type (inner_type, vec_type->get_num_units ());
-      ctxt->record (m_type);
+      ctxt->record_type (m_type);
     }
   }
 
diff --git a/gcc/jit/libgccjit++.h b/gcc/jit/libgccjit++.h
index 4fca2f8f447b..d4b4413384d6 100644
--- a/gcc/jit/libgccjit++.h
+++ b/gcc/jit/libgccjit++.h
@@ -485,6 +485,7 @@ namespace gccjit
     gcc_jit_rvalue *get_inner_rvalue () const;
 
     type get_type ();
+    void set_type (type *new_type);
 
     rvalue access_field (field field,
                         location loc = location ());
@@ -1768,6 +1769,12 @@ rvalue::get_type ()
   return type (gcc_jit_rvalue_get_type (get_inner_rvalue ()));
 }
 
+inline void
+rvalue::set_type (type *new_type)
+{
+  gcc_jit_rvalue_set_type (get_inner_rvalue (), new_type->get_inner_type ());
+}
+
 inline rvalue
 rvalue::access_field (field field,
                      location loc)
diff --git a/gcc/jit/libgccjit.cc b/gcc/jit/libgccjit.cc
index 5a874fc4808a..5684f1322ec0 100644
--- a/gcc/jit/libgccjit.cc
+++ b/gcc/jit/libgccjit.cc
@@ -2005,6 +2005,20 @@ gcc_jit_rvalue_get_type (gcc_jit_rvalue *rvalue)
   return static_cast <gcc_jit_type *> (rvalue->get_type ());
 }
 
+/* Public entrypoint.  See description in libgccjit.h.
+
+   After error-checking, the real work is done by the
+   gcc::jit::recording::rvalue::set_type method, in
+   jit-recording.h.  */
+
+void
+gcc_jit_rvalue_set_type (gcc_jit_rvalue *rvalue, gcc_jit_type *new_type)
+{
+  RETURN_IF_FAIL (rvalue, NULL, NULL, "NULL rvalue");
+
+  rvalue->set_type (new_type);
+}
+
 /* Verify that NUMERIC_TYPE is non-NULL, and that it is a "numeric"
    type i.e. it satisfies gcc::jit::type::is_numeric (), such as the
    result of gcc_jit_context_get_type (GCC_JIT_TYPE_INT).  */
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index 2247c99deb4a..8da389b19dce 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -1108,6 +1108,9 @@ gcc_jit_rvalue_as_object (gcc_jit_rvalue *rvalue);
 extern gcc_jit_type *
 gcc_jit_rvalue_get_type (gcc_jit_rvalue *rvalue);
 
+extern void
+gcc_jit_rvalue_set_type (gcc_jit_rvalue *rvalue, gcc_jit_type *new_type);
+
 /* Integer constants. */
 extern gcc_jit_rvalue *
 gcc_jit_context_new_rvalue_from_int (gcc_jit_context *ctxt,
diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map
index 78b6be9ff36a..eeca14aad645 100644
--- a/gcc/jit/libgccjit.map
+++ b/gcc/jit/libgccjit.map
@@ -349,3 +349,8 @@ LIBGCCJIT_ABI_38 {
   global:
     gcc_jit_type_is_floating_point;
 } LIBGCCJIT_ABI_37;
+
+LIBGCCJIT_ABI_39 {
+  global:
+    gcc_jit_rvalue_set_type;
+} LIBGCCJIT_ABI_38;
diff --git a/gcc/testsuite/jit.dg/test-using-global.c 
b/gcc/testsuite/jit.dg/test-using-global.c
index 8ac9780d2b13..b367ef9b9bf4 100644
--- a/gcc/testsuite/jit.dg/test-using-global.c
+++ b/gcc/testsuite/jit.dg/test-using-global.c
@@ -35,13 +35,21 @@ create_code (gcc_jit_context *ctxt, void *user_data)
   */
   gcc_jit_type *int_type =
     gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+  gcc_jit_type *float_type = gcc_jit_context_get_type (ctxt,
+    GCC_JIT_TYPE_FLOAT);
 
   gcc_jit_lvalue *exported_global =
     gcc_jit_context_new_global (ctxt,
                                NULL,
                                GCC_JIT_GLOBAL_EXPORTED,
-                               int_type,
+                               float_type,
                                "exported_global");
+  gcc_jit_rvalue *r_exported_global =
+    gcc_jit_lvalue_as_rvalue (exported_global);
+  CHECK_VALUE (gcc_jit_rvalue_get_type (r_exported_global), float_type);
+  gcc_jit_rvalue_set_type (r_exported_global, int_type);
+  CHECK_VALUE (gcc_jit_rvalue_get_type (r_exported_global), int_type);
+
   gcc_jit_lvalue *imported_global =
     gcc_jit_context_new_global (ctxt,
                                NULL,
-- 
2.54.0

Reply via email to