Committed to branch dmalcolm/jit: gcc/jit/ * libgccjit.h (gcc_jit_type_get_volatile): New. * libgccjit.map (gcc_jit_type_get_volatile): New. * libgccjit.c (gcc_jit_type_get_volatile): New. * libgccjit++.h (gccjit::type::get_volatile): New. * internal-api.c (gcc::jit::recording::type::get_volatile): New. (gcc::jit::recording::memento_of_get_volatile::replay_into): New. (gcc::jit::recording::memento_of_get_volatile::make_debug_string): New. * internal-api.h (gcc::jit::recording::type::get_volatile): New. (gcc::jit::recording::type::accepts_writes_from): Strip off qualifiers such as "const" and "volatile" from the source type. (gcc::jit::recording::memento_of_get_volatile): New class. (gcc::jit::playback::type::get_volatile): New. * TODO.rst: Update.
gcc/testsuite/ * jit.dg/test-volatile.c: New testcase, to exercise gcc_jit_type_get_volatile, and show a way to work with pre-existing global variables. --- gcc/jit/ChangeLog.jit | 16 +++++++++ gcc/jit/TODO.rst | 2 -- gcc/jit/internal-api.c | 23 +++++++++++++ gcc/jit/internal-api.h | 30 +++++++++++++++- gcc/jit/libgccjit++.h | 7 ++++ gcc/jit/libgccjit.c | 8 +++++ gcc/jit/libgccjit.h | 4 +++ gcc/jit/libgccjit.map | 1 + gcc/testsuite/ChangeLog.jit | 6 ++++ gcc/testsuite/jit.dg/test-volatile.c | 66 ++++++++++++++++++++++++++++++++++++ 10 files changed, 160 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/jit.dg/test-volatile.c diff --git a/gcc/jit/ChangeLog.jit b/gcc/jit/ChangeLog.jit index dd4bf84..56f7b85 100644 --- a/gcc/jit/ChangeLog.jit +++ b/gcc/jit/ChangeLog.jit @@ -1,3 +1,19 @@ +2014-03-04 David Malcolm <dmalc...@redhat.com> + + * libgccjit.h (gcc_jit_type_get_volatile): New. + * libgccjit.map (gcc_jit_type_get_volatile): New. + * libgccjit.c (gcc_jit_type_get_volatile): New. + * libgccjit++.h (gccjit::type::get_volatile): New. + * internal-api.c (gcc::jit::recording::type::get_volatile): New. + (gcc::jit::recording::memento_of_get_volatile::replay_into): New. + (gcc::jit::recording::memento_of_get_volatile::make_debug_string): New. + * internal-api.h (gcc::jit::recording::type::get_volatile): New. + (gcc::jit::recording::type::accepts_writes_from): Strip off + qualifiers such as "const" and "volatile" from the source type. + (gcc::jit::recording::memento_of_get_volatile): New class. + (gcc::jit::playback::type::get_volatile): New. + * TODO.rst: Update. + 2014-03-03 David Malcolm <dmalc...@redhat.com> * libgccjit++.h (gccjit::function::operator()): Add overload for diff --git a/gcc/jit/TODO.rst b/gcc/jit/TODO.rst index 8a2308e..ea09e45 100644 --- a/gcc/jit/TODO.rst +++ b/gcc/jit/TODO.rst @@ -19,8 +19,6 @@ Initial Release * unions * function ptrs - * ability to bind a pre-existing global variable - * expose the statements in the API? (mostly so they can be stringified?) * support more arithmetic ops and comparison modes diff --git a/gcc/jit/internal-api.c b/gcc/jit/internal-api.c index 573dc67..539ba5e 100644 --- a/gcc/jit/internal-api.c +++ b/gcc/jit/internal-api.c @@ -789,6 +789,14 @@ recording::type::get_const () } recording::type * +recording::type::get_volatile () +{ + recording::type *result = new memento_of_get_volatile (this); + m_ctxt->record (result); + return result; +} + +recording::type * recording::memento_of_get_type::dereference () { switch (m_kind) @@ -916,6 +924,21 @@ recording::memento_of_get_const::make_debug_string () "const %s", m_other_type->get_debug_string ()); } +/* gcc::jit::recording::memento_of_get_volatile:: */ + +void +recording::memento_of_get_volatile::replay_into (replayer *) +{ + set_playback_obj (m_other_type->playback_type ()->get_volatile ()); +} + +recording::string * +recording::memento_of_get_volatile::make_debug_string () +{ + return string::from_printf (m_ctxt, + "volatile %s", m_other_type->get_debug_string ()); +} + /* gcc::jit::recording::array_type */ recording::type * diff --git a/gcc/jit/internal-api.h b/gcc/jit/internal-api.h index 7114094a..dd760c7 100644 --- a/gcc/jit/internal-api.h +++ b/gcc/jit/internal-api.h @@ -466,6 +466,7 @@ class type : public memento public: type *get_pointer (); type *get_const (); + type *get_volatile (); /* Get the type obtained when dereferencing this type. @@ -479,7 +480,7 @@ public: /* Is it typesafe to copy to this type from rtype? */ virtual bool accepts_writes_from (type *rtype) { - return this == rtype; + return this == rtype->unqualified (); } /* Strip off "const" etc */ @@ -588,6 +589,28 @@ private: type *m_other_type; }; +/* Result of "gcc_jit_type_get_volatile". */ +class memento_of_get_volatile : public type +{ +public: + memento_of_get_volatile (type *other_type) + : type (other_type->m_ctxt), + m_other_type (other_type) {} + + type *dereference () { return m_other_type->dereference (); } + + /* Strip off the "volatile", giving the underlying type. */ + type *unqualified () { return m_other_type; } + + void replay_into (replayer *); + +private: + string * make_debug_string (); + +private: + type *m_other_type; +}; + class array_type : public type { public: @@ -1744,6 +1767,11 @@ public: return new type (build_qualified_type (m_inner, TYPE_QUAL_CONST)); } + type *get_volatile () const + { + return new type (build_qualified_type (m_inner, TYPE_QUAL_VOLATILE)); + } + private: tree m_inner; }; diff --git a/gcc/jit/libgccjit++.h b/gcc/jit/libgccjit++.h index e7ff5ea..b349ad9 100644 --- a/gcc/jit/libgccjit++.h +++ b/gcc/jit/libgccjit++.h @@ -269,6 +269,7 @@ namespace gccjit gcc_jit_type *get_inner_type () const; type get_pointer (); + type get_volatile (); // Shortcuts for getting values of numeric types: rvalue zero (); @@ -1067,6 +1068,12 @@ type::get_pointer () return type (gcc_jit_type_get_pointer (get_inner_type ())); } +inline type +type::get_volatile () +{ + return type (gcc_jit_type_get_volatile (get_inner_type ())); +} + inline rvalue type::zero () { diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c index d9f63cf..b4c7d44 100644 --- a/gcc/jit/libgccjit.c +++ b/gcc/jit/libgccjit.c @@ -335,6 +335,14 @@ gcc_jit_type_get_const (gcc_jit_type *type) } gcc_jit_type * +gcc_jit_type_get_volatile (gcc_jit_type *type) +{ + RETURN_NULL_IF_FAIL (type, NULL, "NULL type"); + + return (gcc_jit_type *)type->get_volatile (); +} + +gcc_jit_type * gcc_jit_context_new_array_type (gcc_jit_context *ctxt, gcc_jit_location *loc, gcc_jit_type *element_type, diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h index c97cb75..83d4f85 100644 --- a/gcc/jit/libgccjit.h +++ b/gcc/jit/libgccjit.h @@ -391,6 +391,10 @@ gcc_jit_type_get_pointer (gcc_jit_type *type); extern gcc_jit_type * gcc_jit_type_get_const (gcc_jit_type *type); +/* Given type "T", get type "volatile T". */ +extern gcc_jit_type * +gcc_jit_type_get_volatile (gcc_jit_type *type); + /* Given type "T", get type "T[N]" (for a constant N). */ extern gcc_jit_type * gcc_jit_context_new_array_type (gcc_jit_context *ctxt, diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map index c8ad1a4..ed51a62 100644 --- a/gcc/jit/libgccjit.map +++ b/gcc/jit/libgccjit.map @@ -72,6 +72,7 @@ gcc_jit_type_as_object; gcc_jit_type_get_const; gcc_jit_type_get_pointer; + gcc_jit_type_get_volatile; local: *; }; \ No newline at end of file diff --git a/gcc/testsuite/ChangeLog.jit b/gcc/testsuite/ChangeLog.jit index d3ca998..f0548f4 100644 --- a/gcc/testsuite/ChangeLog.jit +++ b/gcc/testsuite/ChangeLog.jit @@ -1,3 +1,9 @@ +2014-03-04 David Malcolm <dmalc...@redhat.com> + + * jit.dg/test-volatile.c: New testcase, to exercise + gcc_jit_type_get_volatile, and show a way to work with pre-existing + global variables. + 2014-02-28 David Malcolm <dmalc...@redhat.com> * jit.dg/test-expressions.c (make_test_of_cast): New, to test new diff --git a/gcc/testsuite/jit.dg/test-volatile.c b/gcc/testsuite/jit.dg/test-volatile.c new file mode 100644 index 0000000..3ef3ca5 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-volatile.c @@ -0,0 +1,66 @@ +#include <stdlib.h> +#include <stdio.h> + +#include "libgccjit.h" + +#include "harness.h" + +volatile int the_volatile; + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: + extern volatile int the_volatile; + + int + test_using_volatile (void) + { + return the_volatile; + } + */ + gcc_jit_type *int_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_type *volatile_int_type = + gcc_jit_type_get_volatile (int_type); + + /* Build the test_fn. */ + gcc_jit_function *test_fn = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + int_type, + "test_using_volatile", + 0, NULL, + 0); + gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL); + gcc_jit_lvalue *read_of_the_volatile = + gcc_jit_rvalue_dereference ( + gcc_jit_context_new_rvalue_from_ptr ( + ctxt, + gcc_jit_type_get_pointer (volatile_int_type), + (void *)&the_volatile), + NULL); + + gcc_jit_block_end_with_return ( + block, NULL, + gcc_jit_lvalue_as_rvalue (read_of_the_volatile)); +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + typedef int (*fn_type) (void); + CHECK_NON_NULL (result); + + fn_type test_using_volatile = + (fn_type)gcc_jit_result_get_code (result, "test_using_volatile"); + CHECK_NON_NULL (test_using_volatile); + + the_volatile = 42; + + /* Call the JIT-generated function. */ + test_using_volatile (); + + CHECK_VALUE (test_using_volatile (), 42); +} + -- 1.7.11.7