On Fri, 2013-10-04 at 15:00 +0000, Joseph S. Myers wrote:
> On Thu, 3 Oct 2013, David Malcolm wrote:
> 
> > Right now all you get back from the result is a "void*" which you're
> > meant to cast to machine code for the CPU.   I guess we could add an
> 
> And right now the library is calling dlopen.  Which means that although 
> what the user gets is a void *, the dynamic linker processing has dealt 
> with registering eh_frame information and the right hooks have been passed 
> through for GDB to see that an object has been loaded and access its debug 
> information.  Is this use of dlopen intended to be part of the interface, 
> or just a temporary hack with users eventually needing to use other 
> interfaces for eh_frame and debug info handling?  (GDB has some support 
> for JITs, but I haven't looked into the details of how it works.)

The use of dlopen does indeed lead to a nice user-experience within gdb;
my plan (vague at this stage) is that by enabling the flag
   GCC_JIT_BOOL_OPTION_DEBUGINFO
on the gcc_jit_context that the client is asking the library to "do the
right thing" to integrate the generated code with a debugger.  Right now
that's implemented using the dlopen hack (and by setting -g), but
potentially we could implement it in other ways.

There are other behaviors due to using dlopen: if you JIT-compile a
function, that function can then be accessed by name from other code
within the process using dlsym.  That could be useful, perhaps, or could
be just weird - perhaps the kludge should be using RTLD_LOCAL so that
symbols are only accessible through the gcc_jit_result object, and don't
pollute the dlsym namespace within the process (though using the term
"pollute" there is perhaps a value-judgment) - not sure.

> > option on the gcc_jit_context for setting which ISA you want code for.
> 
> Even apart from completely separate ISAs, there's also the matter of other 
> command-line options such as -march=, which I'd think users should be able 
> to specify.  And the complication that default options to cc1 can be 
> determined by specs, whether in .h files or from configure options such as 
> --with=arch=, so cc1's defaults may not be the same as the defaults when 
> you run the driver (which are likely to be better defaults for the JIT 
> than cc1's).  And if the user wants to use -march=native (which seems 
> sensible for the common use case of a JIT, generating code for the same 
> system as runs the compiler), that's handled through specs.
> 
> Maybe the driver should be converted to library code so it's possible to 
> run command-line options through it and generate the command line that 
> would get passed to cc1 (but then use that to call a function in the same 
> process - with a different copy of global options data, diagnostic context 
> etc. to avoid any issues from those being initialized twice - rather than 
> running a subprocess).  That would also allow generating the right options 
> for the assembler to pass to the library version of the assembler.
I like these ideas - if nothing else, having the driver as a library
would enable me to get rid of one of the fork&exec pairs in my kludge.

> > > >   * There are some grotesque kludges in internal-api.c, especially in
> > > > how we go from .s assembler files to a DSO (grep for "gross hack" ;) )
> > > 
> > > Apart from making the assembler into a shared library itself, it would 
> > > also be nice to avoid needing those files at all (via an API for writing 
> > > assembler text that doesn't depend on a FILE * pointer, although on GNU 
> > > hosts you can always use in-memory files via open_memstream, which would 
> > > make the internal changes much smaller).  But in the absence of such a 
> > > cleanup, running the assembler via the driver should work, although 
> > > inefficient.
> > 
> > (nods)   Note that all of the kludgery (if that's a word) is hidden
> > inside the library, so we can fix it all up without affecting client
> > code: the client-facing API doesn't expose any of this.
> > 
> > FWIW I added timevars for measuring the invocation of the driver; that
> > kludge makes up about 50% of the overall time taken.  I haven't yet
> > broken that down into assembler vs linker vs fork/exec overhead, but
> > clearly this is something that could use optimization - leading to
> > (very) vague thoughts involving turning parts of binutils into libraries
> > also.
> 
> First I guess it might simply be a library that receives blocks of text 
> that currently go to asm_out_file - but eventually there might be 
> efficiency to be gained by passing binary data to the assembler in some 
> cases (e.g. for large blocks of debug info) rather than generating and 
> then parsing text.  (So some asm_out methods would gain implementations 
> passing such data instead of generating text.)

Agreed - though I think this is something of a version 2 thing, in that
this is an optimization, and a decidedly non-trivial one (converting
binutils into a library, then embedding it).

Thanks for the great ideas.
Dave


Reply via email to