Make sized integer types compatible with normal integer types
diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c
index f721e5c..096c899 100644
--- a/gcc/jit/jit-playback.c
+++ b/gcc/jit/jit-playback.c
@@ -283,6 +283,25 @@
}
/* Construct a playback::type instance (wrapping a tree) for the given
+ sign and number of bits. */
+
+playback::type *
+playback::context::
+make_type (bool is_signed, size_t num_bits)
+{
+ tree int_type;
+ if (is_signed)
+ {
+ int_type = make_signed_type(num_bits);
+ }
+ else
+ {
+ int_type = make_unsigned_type(num_bits);
+ }
+ return new type (int_type);
+}
+
+/* Construct a playback::type instance (wrapping a tree) for the given
array type. */
playback::type *
diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
index b5d71aa..25e0d5c 100644
--- a/gcc/jit/jit-playback.h
+++ b/gcc/jit/jit-playback.h
@@ -67,6 +67,9 @@
get_type (enum gcc_jit_types type);
type *
+ make_type (bool is_signed, size_t num_bits);
+
+ type *
new_array_type (location *loc,
type *element_type,
int num_elements);
diff --git a/gcc/jit/jit-recording.c b/gcc/jit/jit-recording.c
index 1a412b5..5ea2320 100644
--- a/gcc/jit/jit-recording.c
+++ b/gcc/jit/jit-recording.c
@@ -564,8 +564,8 @@
m_compound_types (),
m_globals (),
m_functions (),
- m_signed_int_types(),
- m_unsigned_int_types(),
+ /*m_signed_int_types(),
+ m_unsigned_int_types(),*/
m_FILE_type (NULL),
m_builtins_manager(NULL)
{
@@ -796,6 +796,10 @@
Implements the post-error-checking part of
gcc_jit_context_get_int_type. */
+int nextPowerOfTwo(int x) {
+ return 1 << sizeof(x)*8 - __builtin_clz(x);
+}
+
recording::type *
recording::context::get_int_type (int num_bytes, int is_signed)
{
@@ -805,7 +809,7 @@
Compare with tree.c's make_or_reuse_type. Note that the _SIZE macros
are in bits, rather than bytes.
*/
- const int num_bits = num_bytes * 8;
+ /*const*/ int num_bits = num_bytes * 8;
if (num_bits == INT_TYPE_SIZE)
return get_type (is_signed
? GCC_JIT_TYPE_INT
@@ -832,33 +836,38 @@
: GCC_JIT_TYPE_UINT128_T);
// TODO: check in num_bits > 0?
- tree int_type;
+ /*tree int_type;*/
+ /*printf("Before: %d\n", num_bits);*/
+ /*num_bits = nextPowerOfTwo(num_bits);
+ printf("After: %d\n", num_bits);*/
if (is_signed)
{
- if (tree type = m_signed_int_types[num_bits])
+ /*if (tree type = m_signed_int_types[num_bits])
{
int_type = type;
}
else
- {
- int_type = make_signed_type(num_bits);
- m_signed_int_types[num_bits] = int_type;
- }
+ {*/
+ // FIXME: seems like we cannot create a type here because the ggc is not initialized: instead, create it in
+ // playback.
+ /*int_type = make_signed_type(num_bits);*/
+ /*m_signed_int_types[num_bits] = int_type;
+ }*/
}
else
{
- if (tree type = m_unsigned_int_types[num_bits])
+ /*if (tree type = m_unsigned_int_types[num_bits])
{
int_type = type;
}
else
- {
- int_type = make_unsigned_type(num_bits);
- m_unsigned_int_types[num_bits] = int_type;
- }
+ {*/
+ /*int_type = make_unsigned_type(num_bits);*/
+ /*m_unsigned_int_types[num_bits] = int_type;
+ }*/
}
- recording::type *result = new memento_of_make_type (this, int_type, num_bits);
+ recording::type *result = new memento_of_make_type (this, is_signed, num_bits);
record (result);
return result;
}
@@ -2358,14 +2367,22 @@
size = LONG_LONG_TYPE_SIZE;
break;
case GCC_JIT_TYPE_UINT8_T:
- case GCC_JIT_TYPE_UINT16_T:
- case GCC_JIT_TYPE_UINT32_T:
- case GCC_JIT_TYPE_UINT64_T:
- case GCC_JIT_TYPE_UINT128_T:
case GCC_JIT_TYPE_INT8_T:
+ size = 8;
+ break;
+ case GCC_JIT_TYPE_UINT16_T:
case GCC_JIT_TYPE_INT16_T:
+ size = 16;
+ break;
+ case GCC_JIT_TYPE_UINT32_T:
case GCC_JIT_TYPE_INT32_T:
+ size = 32;
+ break;
+ case GCC_JIT_TYPE_UINT64_T:
case GCC_JIT_TYPE_INT64_T:
+ size = 64;
+ break;
+ case GCC_JIT_TYPE_UINT128_T:
case GCC_JIT_TYPE_INT128_T:
size = 128;
break;
@@ -2378,6 +2395,10 @@
case GCC_JIT_TYPE_LONG_DOUBLE:
size = LONG_DOUBLE_TYPE_SIZE;
break;
+ case GCC_JIT_TYPE_SIZE_T:
+ size = POINTER_TYPE;
+ /*size = TYPE_PRECISION(size_type_node); // TODO: check that this code works.*/
+ break;
default:
/* As this function is called by
'gcc_jit_global_set_initializer' and
@@ -2512,6 +2533,60 @@
}
}
+/* Implementation of pure virtual hook recording::type::is_signed for
+ recording::memento_of_get_type. */
+
+bool
+recording::memento_of_get_type::is_signed () const
+{
+ switch (m_kind)
+ {
+ default: gcc_unreachable ();
+
+ case GCC_JIT_TYPE_SIGNED_CHAR:
+ case GCC_JIT_TYPE_CHAR:
+ case GCC_JIT_TYPE_SHORT:
+ case GCC_JIT_TYPE_INT:
+ case GCC_JIT_TYPE_LONG:
+ case GCC_JIT_TYPE_LONG_LONG:
+ case GCC_JIT_TYPE_INT8_T:
+ case GCC_JIT_TYPE_INT16_T:
+ case GCC_JIT_TYPE_INT32_T:
+ case GCC_JIT_TYPE_INT64_T:
+ case GCC_JIT_TYPE_INT128_T:
+ return true;
+
+ case GCC_JIT_TYPE_VOID:
+ case GCC_JIT_TYPE_VOID_PTR:
+ case GCC_JIT_TYPE_BOOL:
+ case GCC_JIT_TYPE_UNSIGNED_CHAR:
+ case GCC_JIT_TYPE_UNSIGNED_SHORT:
+ case GCC_JIT_TYPE_UNSIGNED_INT:
+ case GCC_JIT_TYPE_UNSIGNED_LONG:
+ case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
+ case GCC_JIT_TYPE_UINT8_T:
+ case GCC_JIT_TYPE_UINT16_T:
+ case GCC_JIT_TYPE_UINT32_T:
+ case GCC_JIT_TYPE_UINT64_T:
+ case GCC_JIT_TYPE_UINT128_T:
+
+ case GCC_JIT_TYPE_FLOAT:
+ case GCC_JIT_TYPE_DOUBLE:
+ case GCC_JIT_TYPE_LONG_DOUBLE:
+
+ case GCC_JIT_TYPE_CONST_CHAR_PTR:
+
+ case GCC_JIT_TYPE_SIZE_T:
+
+ case GCC_JIT_TYPE_FILE_PTR:
+
+ case GCC_JIT_TYPE_COMPLEX_FLOAT:
+ case GCC_JIT_TYPE_COMPLEX_DOUBLE:
+ case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
+ return false;
+ }
+}
+
/* Implementation of pure virtual hook recording::type::is_float for
recording::memento_of_get_type. */
@@ -2761,7 +2836,7 @@
void
recording::memento_of_make_type::replay_into (replayer *r)
{
- set_playback_obj (this);
+ set_playback_obj (r->make_type(m_is_signed, m_num_bits));
}
recording::string *
diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h
index c06874e..343cd6c 100644
--- a/gcc/jit/jit-recording.h
+++ b/gcc/jit/jit-recording.h
@@ -369,8 +369,8 @@
type *m_basic_types[NUM_GCC_JIT_TYPES];
/* Map from num_bits to integer types. */
- tree m_signed_int_types[128];
- tree m_unsigned_int_types[128];
+ /*tree m_signed_int_types[128];
+ tree m_unsigned_int_types[128];*/
type *m_FILE_type;
builtins_manager *m_builtins_manager; // lazily created
@@ -573,6 +573,7 @@
virtual bool is_void () const { return false; }
virtual vector_type *is_vector () { return NULL; }
virtual bool has_known_size () const { return true; }
+ virtual bool is_signed () const = 0;
bool is_numeric () const
{
@@ -613,12 +614,19 @@
bool accepts_writes_from (type *rtype) FINAL OVERRIDE
{
if (m_kind == GCC_JIT_TYPE_VOID_PTR)
+ {
if (rtype->is_pointer ())
{
/* LHS (this) is type (void *), and the RHS is a pointer:
accept it: */
return true;
}
+ }
+ else if (is_int () && rtype->is_int () && get_size () == rtype->get_size () && is_signed () == rtype->is_signed ())
+ {
+ /* LHS (this) is an integer of the size size and sign as rtype. */
+ return true;
+ }
return type::accepts_writes_from (rtype);
}
@@ -629,6 +637,7 @@
type *is_pointer () FINAL OVERRIDE { return dereference (); }
type *is_array () FINAL OVERRIDE { return NULL; }
bool is_void () const FINAL OVERRIDE { return m_kind == GCC_JIT_TYPE_VOID; }
+ bool is_signed () const FINAL OVERRIDE;
public:
void replay_into (replayer *r) FINAL OVERRIDE;
@@ -646,10 +655,10 @@
{
public:
memento_of_make_type (context *ctxt,
- tree int_type,
+ bool is_signed,
size_t num_bits)
: type (ctxt),
- m_type (int_type),
+ m_is_signed (is_signed),
m_num_bits (num_bits) {}
type *dereference () FINAL OVERRIDE { return NULL; };
@@ -667,6 +676,7 @@
type *is_pointer () FINAL OVERRIDE { return NULL; }
type *is_array () FINAL OVERRIDE { return NULL; }
bool is_void () const FINAL OVERRIDE { return false; }
+ bool is_signed () const FINAL OVERRIDE { return m_is_signed; }
public:
void replay_into (replayer *r) FINAL OVERRIDE;
@@ -676,7 +686,7 @@
void write_reproducer (reproducer &r) FINAL OVERRIDE;
private:
- tree m_type;
+ bool m_is_signed;
size_t m_num_bits;
};
@@ -702,6 +712,7 @@
bool is_bool () const FINAL OVERRIDE { return false; }
type *is_pointer () FINAL OVERRIDE { return m_other_type; }
type *is_array () FINAL OVERRIDE { return NULL; }
+ bool is_signed () const FINAL OVERRIDE { return false; }
private:
string * make_debug_string () FINAL OVERRIDE;
@@ -723,12 +734,15 @@
type *dereference () FINAL OVERRIDE { return m_other_type->dereference (); }
+ size_t get_size () FINAL OVERRIDE { return m_other_type->get_size (); };
+
bool is_int () const FINAL OVERRIDE { return m_other_type->is_int (); }
bool is_float () const FINAL OVERRIDE { return m_other_type->is_float (); }
bool is_bool () const FINAL OVERRIDE { return m_other_type->is_bool (); }
type *is_pointer () FINAL OVERRIDE { return m_other_type->is_pointer (); }
type *is_array () FINAL OVERRIDE { return m_other_type->is_array (); }
struct_ *is_struct () FINAL OVERRIDE { return m_other_type->is_struct (); }
+ bool is_signed () const FINAL OVERRIDE { return m_other_type->is_signed (); }
protected:
type *m_other_type;
@@ -844,6 +858,7 @@
type *is_pointer () FINAL OVERRIDE { return NULL; }
type *is_array () FINAL OVERRIDE { return m_element_type; }
int num_elements () { return m_num_elements; }
+ bool is_signed () const FINAL OVERRIDE { return false; }
void replay_into (replayer *) FINAL OVERRIDE;
@@ -877,6 +892,7 @@
bool is_bool () const FINAL OVERRIDE { return false; }
type *is_pointer () FINAL OVERRIDE { return NULL; }
type *is_array () FINAL OVERRIDE { return NULL; }
+ bool is_signed () const FINAL OVERRIDE { return false; }
void replay_into (replayer *) FINAL OVERRIDE;
@@ -990,6 +1006,7 @@
bool is_bool () const FINAL OVERRIDE { return false; }
type *is_pointer () FINAL OVERRIDE { return NULL; }
type *is_array () FINAL OVERRIDE { return NULL; }
+ bool is_signed () const FINAL OVERRIDE { return false; }
bool has_known_size () const FINAL OVERRIDE { return m_fields != NULL; }
diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c
index 3758400..e03817f 100644
--- a/gcc/jit/libgccjit.c
+++ b/gcc/jit/libgccjit.c
@@ -537,6 +537,19 @@
/* Public entrypoint. See description in libgccjit.h.
After error-checking, the real work is done by the
+ gcc::jit::recording::type::get_size method, in
+ jit-recording.c. */
+
+ssize_t
+gcc_jit_type_get_size (gcc_jit_type *type)
+{
+ RETURN_VAL_IF_FAIL (type->is_int (), -1, NULL, NULL, "only getting the size of an int type is supported for now");
+ return type->get_size ();
+}
+
+/* Public entrypoint. See description in libgccjit.h.
+
+ After error-checking, the real work is done by the
gcc::jit::recording::type::is_array method, in
jit-recording.c. */
@@ -1865,7 +1878,7 @@
RETURN_NULL_IF_FAIL (a, ctxt, loc, "NULL a");
RETURN_NULL_IF_FAIL (b, ctxt, loc, "NULL b");
RETURN_NULL_IF_FAIL_PRINTF4 (
- a->get_type ()->unqualified () == b->get_type ()->unqualified (),
+ compatible_types (a->get_type (), b->get_type ()),
ctxt, loc,
"mismatching types for binary op:"
" a: %s (type: %s) b: %s (type: %s)",
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index e4ec6cf..8c737f1 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -612,6 +612,10 @@
extern gcc_jit_type *
gcc_jit_type_get_volatile (gcc_jit_type *type);
+/* Given type "T", get its size. */
+extern ssize_t
+gcc_jit_type_get_size (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 a30cca5..53b4246 100644
--- a/gcc/jit/libgccjit.map
+++ b/gcc/jit/libgccjit.map
@@ -252,3 +252,8 @@
gcc_jit_context_new_rvalue_from_struct;
gcc_jit_context_new_rvalue_from_array;
} LIBGCCJIT_ABI_20;
+
+LIBGCCJIT_ABI_22 {
+ global:
+ gcc_jit_type_get_size;
+} LIBGCCJIT_ABI_21;