diff options
author | Andrea Corallo <andrea.corallo@arm.com> | 2020-05-30 10:33:08 +0100 |
---|---|---|
committer | Andrea Corallo <andrea.corallo@arm.com> | 2020-09-11 12:18:59 +0200 |
commit | 4ecc0061c400102859dd630cce84d1cc5be0fbf7 (patch) | |
tree | 7d5e9b91b960800e48074ba848e723990048acaf /gcc/jit/jit-playback.c | |
parent | 15545563128f0240192c263522d4a36b7f86250f (diff) | |
download | gcc-4ecc0061c400102859dd630cce84d1cc5be0fbf7.zip gcc-4ecc0061c400102859dd630cce84d1cc5be0fbf7.tar.gz gcc-4ecc0061c400102859dd630cce84d1cc5be0fbf7.tar.bz2 |
libgccjit: Add new gcc_jit_global_set_initializer entry point
gcc/jit/ChangeLog
2020-08-01 Andrea Corallo <andrea.corallo@arm.com>
* docs/topics/compatibility.rst (LIBGCCJIT_ABI_14): New ABI tag.
* docs/topics/expressions.rst (gcc_jit_global_set_initializer):
Document new entry point in section 'Global variables'.
* jit-playback.c (global_new_decl, global_finalize_lvalue): New
method.
(playback::context::new_global): Make use of global_new_decl,
global_finalize_lvalue.
(load_blob_in_ctor): New template function in use by the
following.
(playback::context::new_global_initialized): New method.
* jit-playback.h (class context): Decl 'new_global_initialized',
'global_new_decl', 'global_finalize_lvalue'.
(lvalue::set_initializer): Add implementation.
* jit-recording.c (recording::memento_of_get_pointer::get_size)
(recording::memento_of_get_type::get_size): Add implementation.
(recording::global::write_initializer_reproducer): New function in
use by 'recording::global::write_reproducer'.
(recording::global::replay_into)
(recording::global::write_to_dump)
(recording::global::write_reproducer): Handle
initialized case.
* jit-recording.h (class type): Decl 'get_size' and
'num_elements'.
* libgccjit++.h (class lvalue): Declare new 'set_initializer'
method.
(class lvalue): Decl 'is_global' and 'set_initializer'.
(class global) Decl 'write_initializer_reproducer'. Add
'm_initializer', 'm_initializer_num_bytes' fields. Implement
'set_initializer'. Add a destructor to free 'm_initializer'.
* libgccjit.c (gcc_jit_global_set_initializer): New function.
* libgccjit.h (gcc_jit_global_set_initializer): New function
declaration.
* libgccjit.map (LIBGCCJIT_ABI_14): New ABI tag.
gcc/testsuite/ChangeLog
2020-08-01 Andrea Corallo <andrea.corallo@arm.com>
* jit.dg/all-non-failing-tests.h: Add test-blob.c.
* jit.dg/test-global-set-initializer.c: New testcase.
Diffstat (limited to 'gcc/jit/jit-playback.c')
-rw-r--r-- | gcc/jit/jit-playback.c | 107 |
1 files changed, 101 insertions, 6 deletions
diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c index 0fddf04..4fac64d 100644 --- a/gcc/jit/jit-playback.c +++ b/gcc/jit/jit-playback.c @@ -510,14 +510,14 @@ new_function (location *loc, return func; } -/* Construct a playback::lvalue instance (wrapping a tree). */ +/* In use by new_global and new_global_initialized. */ -playback::lvalue * +tree playback::context:: -new_global (location *loc, - enum gcc_jit_global_kind kind, - type *type, - const char *name) +global_new_decl (location *loc, + enum gcc_jit_global_kind kind, + type *type, + const char *name) { gcc_assert (type); gcc_assert (name); @@ -547,6 +547,15 @@ new_global (location *loc, if (loc) set_tree_location (inner, loc); + return inner; +} + +/* In use by new_global and new_global_initialized. */ + +playback::lvalue * +playback::context:: +global_finalize_lvalue (tree inner) +{ varpool_node::get_create (inner); varpool_node::finalize_decl (inner); @@ -556,6 +565,92 @@ new_global (location *loc, return new lvalue (this, inner); } +/* Construct a playback::lvalue instance (wrapping a tree). */ + +playback::lvalue * +playback::context:: +new_global (location *loc, + enum gcc_jit_global_kind kind, + type *type, + const char *name) +{ + tree inner = global_new_decl (loc, kind, type, name); + + return global_finalize_lvalue (inner); +} + +/* Fill 'constructor_elements' with the memory content of + 'initializer'. Each element of the initializer is of the size of + type T. In use by new_global_initialized.*/ + +template<typename T> +static void +load_blob_in_ctor (vec<constructor_elt, va_gc> *&constructor_elements, + size_t num_elem, + const void *initializer) +{ + /* Loosely based on 'output_init_element' c-typeck.c:9691. */ + const T *p = (const T *)initializer; + tree node = make_unsigned_type (BITS_PER_UNIT * sizeof (T)); + for (size_t i = 0; i < num_elem; i++) + { + constructor_elt celt = + { build_int_cst (long_unsigned_type_node, i), + build_int_cst (node, p[i]) }; + vec_safe_push (constructor_elements, celt); + } +} + +/* Construct an initialized playback::lvalue instance (wrapping a + tree). */ + +playback::lvalue * +playback::context:: +new_global_initialized (location *loc, + enum gcc_jit_global_kind kind, + type *type, + size_t element_size, + size_t initializer_num_elem, + const void *initializer, + const char *name) +{ + tree inner = global_new_decl (loc, kind, type, name); + + vec<constructor_elt, va_gc> *constructor_elements = NULL; + + switch (element_size) + { + case 1: + load_blob_in_ctor<uint8_t> (constructor_elements, initializer_num_elem, + initializer); + break; + case 2: + load_blob_in_ctor<uint16_t> (constructor_elements, initializer_num_elem, + initializer); + break; + case 4: + load_blob_in_ctor<uint32_t> (constructor_elements, initializer_num_elem, + initializer); + break; + case 8: + load_blob_in_ctor<uint64_t> (constructor_elements, initializer_num_elem, + initializer); + break; + default: + /* This function is serving on sizes returned by 'get_size', + these are all covered by the previous cases. */ + gcc_unreachable (); + } + /* Compare with 'pop_init_level' c-typeck.c:8780. */ + tree ctor = build_constructor (type->as_tree (), constructor_elements); + constructor_elements = NULL; + + /* Compare with 'store_init_value' c-typeck.c:7555. */ + DECL_INITIAL (inner) = ctor; + + return global_finalize_lvalue (inner); +} + /* Implementation of the various gcc::jit::playback::context::new_rvalue_from_const <HOST_TYPE> methods. |