Skip to content

Commit

Permalink
Make it possible to register a LLVM type constructor for codegen.
Browse files Browse the repository at this point in the history
  • Loading branch information
maleadt committed Jul 20, 2023
1 parent bd8350b commit 9b51354
Show file tree
Hide file tree
Showing 8 changed files with 35 additions and 14 deletions.
10 changes: 4 additions & 6 deletions base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,12 @@
# name::TypeName
# super::Type
# parameters::Tuple
# names::Tuple
# types::Tuple
# ctor
# instance
# size::Int32
# abstract::Bool
# mutable::Bool
# pointerfree::Bool
# layout
# llvm_ctor
# hash::UInt32
# flags::UInt16
#end

#struct Union <: Type
Expand Down
2 changes: 2 additions & 0 deletions src/builtin_proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ DECLARE_BUILTIN(throw);
DECLARE_BUILTIN(tuple);
DECLARE_BUILTIN(typeassert);
DECLARE_BUILTIN(_typebody);
DECLARE_BUILTIN(_typector);
DECLARE_BUILTIN(typeof);
DECLARE_BUILTIN(_typevar);
DECLARE_BUILTIN(donotdelete);
Expand All @@ -66,6 +67,7 @@ JL_CALLABLE(jl_f__structtype);
JL_CALLABLE(jl_f__abstracttype);
JL_CALLABLE(jl_f__primitivetype);
JL_CALLABLE(jl_f__setsuper);
JL_CALLABLE(jl_f__typector);
JL_CALLABLE(jl_f__equiv_typedef);
JL_CALLABLE(jl_f_get_binding_type);
JL_CALLABLE(jl_f_set_binding_type);
Expand Down
12 changes: 12 additions & 0 deletions src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -1787,6 +1787,17 @@ JL_CALLABLE(jl_f__typebody)
return jl_nothing;
}

JL_CALLABLE(jl_f__typector)
{
JL_NARGS(_typector!, 2, 2);
jl_datatype_t *dt = (jl_datatype_t*)jl_unwrap_unionall(args[0]);
JL_TYPECHK(_typector!, datatype, (jl_value_t*)dt);
jl_value_t* ctor = args[1];
JL_TYPECHK(_typector!, pointer, ctor);
dt->llvm_constructor = (jl_llvm_type_constructor_t) jl_unbox_long(ctor);
return jl_nothing;
}

// this is a heuristic for allowing "redefining" a type to something identical
static int equiv_type(jl_value_t *ta, jl_value_t *tb)
{
Expand Down Expand Up @@ -2037,6 +2048,7 @@ void jl_init_primitives(void) JL_GC_DISABLED
add_builtin_func("_primitivetype", jl_f__primitivetype);
add_builtin_func("_setsuper!", jl_f__setsuper);
jl_builtin__typebody = add_builtin_func("_typebody!", jl_f__typebody);
add_builtin_func("_typector!", jl_f__typector);
add_builtin_func("_equiv_typedef", jl_f__equiv_typedef);
jl_builtin_donotdelete = add_builtin_func("donotdelete", jl_f_donotdelete);
jl_builtin_compilerbarrier = add_builtin_func("compilerbarrier", jl_f_compilerbarrier);
Expand Down
2 changes: 2 additions & 0 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,8 @@ Type *jl_type_to_llvm_impl(jl_value_t *jt, LLVMContextRef ctxt, bool *isboxed)
static Type *bitstype_to_llvm(jl_value_t *bt, LLVMContext &ctxt, bool llvmcall = false)
{
assert(jl_is_primitivetype(bt));
if (((jl_datatype_t*)bt)->llvm_constructor != NULL)
return (Type*) ((jl_datatype_t*)bt)->llvm_constructor(&ctxt);
if (bt == (jl_value_t*)jl_bool_type)
return llvmcall ? getInt1Ty(ctxt) : getInt8Ty(ctxt);
if (bt == (jl_value_t*)jl_int32_type)
Expand Down
1 change: 1 addition & 0 deletions src/datatype.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ jl_datatype_t *jl_new_uninitialized_datatype(void)
t->layout = NULL;
t->types = NULL;
t->instance = NULL;
t->llvm_constructor = NULL;
return t;
}

Expand Down
14 changes: 8 additions & 6 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -2577,25 +2577,27 @@ void jl_init_types(void) JL_GC_DISABLED
jl_datatype_type->name->wrapper = (jl_value_t*)jl_datatype_type;
jl_datatype_type->super = type_type;
jl_datatype_type->parameters = jl_emptysvec;
jl_datatype_type->name->n_uninitialized = 8 - 3;
jl_datatype_type->name->names = jl_perm_symsvec(8,
jl_datatype_type->name->n_uninitialized = 9 - 3;
jl_datatype_type->name->names = jl_perm_symsvec(9,
"name",
"super",
"parameters",
"types",
"instance",
"layout",
"hash",
"flags"); // "hasfreetypevars", "isconcretetype", "isdispatchtuple", "isbitstype", "zeroinit", "has_concrete_subtype", "maybe_subtype_of_cache"
jl_datatype_type->types = jl_svec(8,
"flags", // "hasfreetypevars", "isconcretetype", "isdispatchtuple", "isbitstype", "zeroinit", "has_concrete_subtype", "maybe_subtype_of_cache"
"llvm_constructor");
jl_datatype_type->types = jl_svec(9,
jl_typename_type,
jl_datatype_type,
jl_simplevector_type,
jl_simplevector_type,
jl_any_type, // instance
jl_any_type /*instance*/,
jl_any_type /*jl_voidpointer_type*/,
jl_any_type /*jl_int32_type*/,
jl_any_type /*jl_uint16_type*/);
jl_any_type /*jl_uint16_type*/,
jl_any_type /*jl_voidpointer_type*/);
const static uint32_t datatype_constfields[1] = { 0x00000057 }; // (1<<0)|(1<<1)|(1<<2)|(1<<4)|(1<<6)
const static uint32_t datatype_atomicfields[1] = { 0x00000028 }; // (1<<3)|(1<<5)
jl_datatype_type->name->constfields = datatype_constfields;
Expand Down
3 changes: 3 additions & 0 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,8 @@ typedef struct {
// };
} jl_datatype_layout_t;

typedef void *(*jl_llvm_type_constructor_t)(void *ctx);

typedef struct _jl_datatype_t {
JL_DATA_TYPE
jl_typename_t *name;
Expand All @@ -574,6 +576,7 @@ typedef struct _jl_datatype_t {
uint16_t ismutationfree:1; // whether any mutable memory is reachable through this type (in the type or via fields)
uint16_t isidentityfree:1; // whether this type or any object reachable through its fields has non-content-based identity
uint16_t smalltag:6; // whether this type has a small-tag optimization
jl_llvm_type_constructor_t llvm_constructor; // callable function taking a context argument
} jl_datatype_t;

typedef struct _jl_vararg_t {
Expand Down
5 changes: 3 additions & 2 deletions src/staticdata.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ extern "C" {
// TODO: put WeakRefs on the weak_refs list during deserialization
// TODO: handle finalizers

#define NUM_TAGS 158
#define NUM_TAGS 159

// An array of references that need to be restored from the sysimg
// This is a manually constructed dual of the gvars array, which would be produced by codegen for Julia code, for C.
Expand Down Expand Up @@ -273,6 +273,7 @@ jl_value_t **const*const get_tags(void) {
INSERT_TAG(jl_builtin__expr);
INSERT_TAG(jl_builtin_ifelse);
INSERT_TAG(jl_builtin__typebody);
INSERT_TAG(jl_builtin__typector);
INSERT_TAG(jl_builtin_donotdelete);
INSERT_TAG(jl_builtin_compilerbarrier);
INSERT_TAG(jl_builtin_getglobal);
Expand Down Expand Up @@ -447,7 +448,7 @@ static const jl_fptr_args_t id_to_fptrs[] = {
&jl_f_arrayref, &jl_f_const_arrayref, &jl_f_arrayset, &jl_f_arraysize, &jl_f_apply_type,
&jl_f_applicable, &jl_f_invoke, &jl_f_sizeof, &jl_f__expr, &jl_f__typevar,
&jl_f_ifelse, &jl_f__structtype, &jl_f__abstracttype, &jl_f__primitivetype,
&jl_f__typebody, &jl_f__setsuper, &jl_f__equiv_typedef, &jl_f_get_binding_type,
&jl_f__typebody, &jl_f__typector, &jl_f__setsuper, &jl_f__equiv_typedef, &jl_f_get_binding_type,
&jl_f_set_binding_type, &jl_f_opaque_closure_call, &jl_f_donotdelete, &jl_f_compilerbarrier,
&jl_f_getglobal, &jl_f_setglobal, &jl_f_finalizer, &jl_f__compute_sparams, &jl_f__svec_ref,
NULL };
Expand Down

0 comments on commit 9b51354

Please sign in to comment.