diff options
author | Andrea Corallo <andrea.corallo@arm.com> | 2019-07-04 15:46:00 +0000 |
---|---|---|
committer | Andrea Corallo <akrl@gcc.gnu.org> | 2019-07-04 15:46:00 +0000 |
commit | ee118c14f71f43a4b82c439cd4381e034bd2786a (patch) | |
tree | 023d5a6423cfaf816e0dc16b7c00aafb8c673194 /gcc/jit/jit-playback.c | |
parent | ebebc928d8b0d17676e751848892f927373b1fe5 (diff) | |
download | gcc-ee118c14f71f43a4b82c439cd4381e034bd2786a.zip gcc-ee118c14f71f43a4b82c439cd4381e034bd2786a.tar.gz gcc-ee118c14f71f43a4b82c439cd4381e034bd2786a.tar.bz2 |
introduce gcc_jit_context_new_bitfield
gcc/jit/ChangeLog:
2019-07-04 Andrea Corallo <andrea.corallo@arm.com>
* docs/topics/compatibility.rst (LIBGCCJIT_ABI_12): New ABI tag.
* docs/topics/types.rst: Add gcc_jit_context_new_bitfield.
* jit-common.h (namespace recording): Add class bitfield.
* jit-playback.c:
(DECL_C_BIT_FIELD, SET_DECL_C_BIT_FIELD): Add macros.
(playback::context::new_bitfield): New method.
(playback::compound_type::set_fields): Add bitfield support.
(playback::lvalue::mark_addressable): Was jit_mark_addressable make this
a method of lvalue plus return a bool to communicate success.
(playback::lvalue::get_address): Check for jit_mark_addressable return
value.
* jit-playback.h (new_bitfield): New method.
(class bitfield): New class.
(class lvalue): Add jit_mark_addressable method.
* jit-recording.c (recording::context::new_bitfield): New method.
(recording::bitfield::replay_into): New method.
(recording::bitfield::write_to_dump): Likewise.
(recording::bitfield::make_debug_string): Likewise.
(recording::bitfield::write_reproducer): Likewise.
* jit-recording.h (class context): Add new_bitfield method.
(class field): Make it derivable by class bitfield.
(class bitfield): Add new class.
* libgccjit++.h (class context): Add new_bitfield method.
* libgccjit.c (struct gcc_jit_bitfield): New structure.
(gcc_jit_context_new_bitfield): New function.
* libgccjit.h
(LIBGCCJIT_HAVE_gcc_jit_context_new_bitfield) New macro.
(gcc_jit_context_new_bitfield): New function.
* libgccjit.map (LIBGCCJIT_ABI_12) New ABI tag.
gcc/testsuite/ChangeLog:
2019-07-04 Andrea Corallo <andrea.corallo@arm.com>
* jit.dg/all-non-failing-tests.h: Add test-accessing-bitfield.c.
* jit.dg/test-accessing-bitfield.c: New testcase.
* jit.dg/test-error-gcc_jit_context_new_bitfield-invalid-type.c:
Likewise.
* jit.dg/test-error-gcc_jit_context_new_bitfield-invalid-width.c:
Likewise.
* jit.dg/test-error-gcc_jit_lvalue_get_address-bitfield.c:
Likewise.
From-SVN: r273086
Diffstat (limited to 'gcc/jit/jit-playback.c')
-rw-r--r-- | gcc/jit/jit-playback.c | 91 |
1 files changed, 79 insertions, 12 deletions
diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c index b74495c..942c730 100644 --- a/gcc/jit/jit-playback.c +++ b/gcc/jit/jit-playback.c @@ -47,6 +47,13 @@ along with GCC; see the file COPYING3. If not see #include "jit-builtins.h" #include "jit-tempdir.h" +/* Compare with gcc/c-family/c-common.h: DECL_C_BIT_FIELD, + SET_DECL_C_BIT_FIELD. + These are redefined here to avoid depending from the C frontend. */ +#define DECL_JIT_BIT_FIELD(NODE) \ + (DECL_LANG_FLAG_4 (FIELD_DECL_CHECK (NODE)) == 1) +#define SET_DECL_JIT_BIT_FIELD(NODE) \ + (DECL_LANG_FLAG_4 (FIELD_DECL_CHECK (NODE)) = 1) /* gcc::jit::playback::context::build_cast uses the convert.h API, which in turn requires the frontend to provide a "convert" @@ -263,6 +270,46 @@ new_field (location *loc, return new field (decl); } +/* Construct a playback::bitfield instance (wrapping a tree). */ + +playback::field * +playback::context:: +new_bitfield (location *loc, + type *type, + int width, + const char *name) +{ + gcc_assert (type); + gcc_assert (name); + gcc_assert (width); + + /* compare with c/c-decl.c:grokfield, grokdeclarator and + check_bitfield_type_and_width. */ + + tree tree_type = type->as_tree (); + gcc_assert (INTEGRAL_TYPE_P (tree_type)); + tree tree_width = build_int_cst (integer_type_node, width); + if (compare_tree_int (tree_width, TYPE_PRECISION (tree_type)) > 0) + { + add_error ( + loc, + "width of bit-field %s (width: %i) is wider than its type (width: %i)", + name, width, TYPE_PRECISION (tree_type)); + return NULL; + } + + tree decl = build_decl (UNKNOWN_LOCATION, FIELD_DECL, + get_identifier (name), type->as_tree ()); + DECL_NONADDRESSABLE_P (decl) = true; + DECL_INITIAL (decl) = tree_width; + SET_DECL_JIT_BIT_FIELD (decl); + + if (loc) + set_tree_location (decl, loc); + + return new field (decl); +} + /* Construct a playback::compound_type instance (wrapping a tree). */ playback::compound_type * @@ -295,8 +342,15 @@ playback::compound_type::set_fields (const auto_vec<playback::field *> *fields) for (unsigned i = 0; i < fields->length (); i++) { field *f = (*fields)[i]; - DECL_CONTEXT (f->as_tree ()) = t; - fieldlist = chainon (f->as_tree (), fieldlist); + tree x = f->as_tree (); + DECL_CONTEXT (x) = t; + if (DECL_JIT_BIT_FIELD (x)) + { + unsigned HOST_WIDE_INT width = tree_to_uhwi (DECL_INITIAL (x)); + DECL_SIZE (x) = bitsize_int (width); + DECL_BIT_FIELD (x) = 1; + } + fieldlist = chainon (x, fieldlist); } fieldlist = nreverse (fieldlist); TYPE_FIELDS (t) = fieldlist; @@ -1197,20 +1251,31 @@ dereference (location *loc) return new lvalue (get_context (), datum); } -/* Mark EXP saying that we need to be able to take the +/* Mark the lvalue saying that we need to be able to take the address of it; it should not be allocated in a register. - Compare with e.g. c/c-typeck.c: c_mark_addressable. */ + Compare with e.g. c/c-typeck.c: c_mark_addressable really_atomic_lvalue. + Returns false if a failure occurred (an error will already have been + added to the active context for this case). */ -static void -jit_mark_addressable (tree exp) +bool +playback::lvalue:: +mark_addressable (location *loc) { - tree x = exp; + tree x = as_tree ();; while (1) switch (TREE_CODE (x)) { case COMPONENT_REF: - /* (we don't yet support bitfields) */ + if (DECL_JIT_BIT_FIELD (TREE_OPERAND (x, 1))) + { + gcc_assert (gcc::jit::active_playback_ctxt); + gcc::jit:: + active_playback_ctxt->add_error (loc, + "cannot take address of " + "bit-field"); + return false; + } /* fallthrough */ case ADDR_EXPR: case ARRAY_REF: @@ -1222,7 +1287,7 @@ jit_mark_addressable (tree exp) case COMPOUND_LITERAL_EXPR: case CONSTRUCTOR: TREE_ADDRESSABLE (x) = 1; - return; + return true; case VAR_DECL: case CONST_DECL: @@ -1234,7 +1299,7 @@ jit_mark_addressable (tree exp) TREE_ADDRESSABLE (x) = 1; /* fallthrough */ default: - return; + return true; } } @@ -1251,8 +1316,10 @@ get_address (location *loc) tree ptr = build1 (ADDR_EXPR, t_ptrtype, t_lvalue); if (loc) get_context ()->set_tree_location (ptr, loc); - jit_mark_addressable (t_lvalue); - return new rvalue (get_context (), ptr); + if (mark_addressable (loc)) + return new rvalue (get_context (), ptr); + else + return NULL; } /* The wrapper subclasses are GC-managed, but can own non-GC memory. |