gcc_jit_context (was Re: Python API (was Re: Build errors))

David Malcolm dmalcolm@redhat.com
Tue Jan 1 00:00:00 GMT 2013


On Thu, 2013-10-24 at 03:36 -0700, Simon Feltman wrote:
> On Wed, Oct 23, 2013 at 10:20 PM, Simon Feltman <s.feltman@gmail.com> wrote:
> > ... This is well beyond my knowledge of compiler architecture,
> > but it seems like this could be cleaner?
> >
> >     the_type = ctxt.get_type(gccjit.Type.INT)
> >     local_i = fn.new_local(the_type, b"i")
> >
> > could be:
> >     local_i = fn.new_local(gccjit.Type.INT, b"i")
> 
> Digging into this a bit more, it looks like the gccjit API is sort of
> synthesizing the context dependence for types anyhow. e.g. gcc
> internals already seem to be defining the type nodes as globals
> (uint64_type_node). So perhaps the API is attempting to present a new
> model which the implementation may morph into?

Yes: as well as the JIT work, I'm also trying to modularize the core of
GCC: in the future I want to support multiple contexts of GCC state
within one process; there's now a "gcc::context" object in GCC proper,
though currently it only has one field (the pass manager). [1]

Hence I want the API to avoid a concept of "the" int type within the
process, instead, merely a given context's int type.  As you found out,
that part is currently somewhat smoke-and-mirrors.

BTW, internally most of the objects in the library already "know" which
context they belong to, and it would be easy to add that to the rest, so
it's not strictly necessary for many of the C entrypoints to be passed a
context pointer.  Some of the more recent entrypoints don't bother e.g.:
gcc_jit_rvalue_dereference.

So I've been thinking about reworking some of the existing C API to do
this, eliminating the context ptr from them.  So e.g. 

  extern gcc_jit_rvalue *
  gcc_jit_context_new_rvalue_from_int (gcc_jit_context *ctxt,
                                       gcc_jit_type *type,
                                       int value);
  extern gcc_jit_rvalue *
  gcc_jit_context_zero (gcc_jit_context *ctxt,
                        gcc_jit_type *type);

might become:

  extern gcc_jit_rvalue *
  gcc_jit_type_rvalue_from_int (gcc_jit_type *type,
                                int value);
  extern gcc_jit_rvalue *
  gcc_jit_type_zero (gcc_jit_type *type);

That way you'd generally go from a context to make your types, globals
and functions, and then you'd invoke methods on the types to make
rvalues, and on the functions to add statements (with a few exceptions
e.g. perhaps a rvalue *gcc_jit_function_make_call?)

The above may be my Python background speaking (in that in Python
there's such a strong relationship between types and making instances);
I wonder how natural such an API sounds to others on the list?

As another example, for binary ops; currently we have:

  extern gcc_jit_rvalue *
  gcc_jit_context_new_binary_op (gcc_jit_context *ctxt,
                                 gcc_jit_location *loc,
                                 enum gcc_jit_binary_op op,
                                 gcc_jit_type *result_type,
                                 gcc_jit_rvalue *a, gcc_jit_rvalue *b);

which might become:

  extern gcc_jit_rvalue *
  gcc_jit_type_binary_op (gcc_jit_type *result_type,
                          gcc_jit_location *loc,
                          enum gcc_jit_binary_op op,
                          gcc_jit_rvalue *a, gcc_jit_rvalue *b);

which itself raises issues of casts, which I've been mostly ignoring for
now.  FWIW gcc_jit_function_add_assignment currently adds a
type-coercion if the types of the LHS and RHS are different, but I'm
thinking of dropping that, and requiring an explicit cast (with a new
API entrypoint for that).  The testsuite fully passes if I drop the
implicit casts.

Thoughts?

Dave
[1] fwiw the gcc::context in GCC proper is independent from the
gcc::jit::context in gcc/jit/internal-api.[hc].  One day a jit context
might own a gcc::context, perhaps.



More information about the Jit mailing list