llvm-d

Moritz Maxeiner moritz at ucworks.org
Sat Mar 23 13:22:31 PDT 2013


On Saturday, 23 March 2013 at 16:37:35 UTC, Jens Mueller wrote:
> Moritz Maxeiner wrote:
>> On Saturday, 23 March 2013 at 10:31:30 UTC, Jens Mueller wrote:
>> >Moritz Maxeiner wrote:
>> >>On Saturday, 23 March 2013 at 09:30:07 UTC, Jens Mueller 
>> >>wrote:
>> >>>Moritz Maxeiner wrote:
>> >>>>A couple of more things I forgot to mention:
>> >>>>
>> >>>>- You will need to additionally add bindings for all the
>> >>>>>>LLVMInitialize"TARGET_NAME"{TargetInfo,Target,TargetMC,AsmParser,AsmPrinter,Disassembler}
>> >>>>functions. They reside inside the target libraries and not
>> >>>>inside
>> >>>>llvm-c, which is why only translating the C API won't get 
>> >>>>you
>> >>>>them.
>> >>>>The LLVMInitializeNativeTarget function , which is 
>> >>>>necessary
>> >>>>to
>> >>>>use
>> >>>>LLVM for jitting - otherwise you'll only have access to
>> >>>>interpreting, which is horribly slow - uses them, but it 
>> >>>>is a
>> >>>>static
>> >>>>inline function and as such does not get exposed because 
>> >>>>LLVM
>> >>>>builds
>> >>>>with the option to hide all inline functions. That is not a
>> >>>>problem
>> >>>>for C, as this function gets defined in the header, but for
>> >>>>D it
>> >>>>is
>> >>>>a big problem, because you cannot access
>> >>>>LLVMInitializeNativeTarget.
>> >>>>You need to recreate it in D by using all the functions it
>> >>>>references. Of course, you'll also have to accomodate the
>> >>>>fact
>> >>>>that
>> >>>>these referenced functions may or may not be compiled in
>> >>>>depending
>> >>>>on which target where selected when compiling LLVM.
>> >>>
>> >>>Do you happen to know why these functions are not declared 
>> >>>in
>> >>>the
>> >>>header
>> >>>files. I mean when using the C interface in C I wouldn't 
>> >>>even
>> >>>know
>> >>>that
>> >>>these functions exist.
>> >>
>> >>I suspect it is because of LLVM's internal structure. Each
>> >>supported
>> >>target is presented by its own directory and they are afaict
>> >>mutually independent from one another, "so their 
>> >>initialiation
>> >>routines should be part of them themselves" I would guess, 
>> >>but I
>> >>don't know, sorry.
>> >>Also, when using the C interface in C there is little need to
>> >>know
>> >>them because they get encapsulated in 
>> >>LLVMInitializeAllTargets
>> >>and
>> >>LLVMInitializeNativeTarget.
>> >
>> >Not sure whether this fixes the problem completely. Can you 
>> >check
>> >https://github.com/jkm/deimos-llvm/blob/master/deimos/llvm/c/target.d#L157
>> >I came up with this solution to replace the macros in the C
>> >binding.
>> 
>> It looks mostly okay to me with one problem: Afaict the code
>> enforces the presence of the initialization routines of all 
>> targets,
>> e.g. if one target is missing LLVMInitializeAllTargets will not
>> link, as there are undefined references for that missing 
>> target, but
>> LLVM may or may not be compiled with that target so you cannot
>> enforce its presence in the bindings. For runtime loading the
>> solution I used was to check the function pointer for null; for
>> linking you have this problem: When using linking, knowing 
>> which
>> targets are available happens at link time (when the LLVM 
>> libraries
>> are linked in), which means you cannot use any compile time 
>> tricks
>> for automatic detection of which targets are available.
>> The only solution for that problem I can think of would be to 
>> use
>> runtime reflection and check at runtime for each initialiation
>> routine if it is a callable function, but afaik D only has 
>> compile
>> time reflection.
>
> I wonder how they do it in C. Don't you have to set a macro?

Afaict they rely on the fact that when you install llvm on your 
system you get the {/usr/include/}llvm/Config/Targets.def file, 
in which is set what targets LLVM was compiled with (it gets 
generated at LLVM compile-time). Then the Target.h, in which the 
LLVMInitializeAllTargets function rests, includes that file and 
does some of that macro-voodoo that makes C/C++ so "lovable" to 
only create calls for the targets enabled in the Targets.def file 
when LLVMInitalizeAllTargets gets inlined. Of course, that 
solution isn't viable because afaik you cannot access filesystem 
IO functions in D CTFE, meaning the Targets.def file is useless 
to you. <rant>Hooray for the C/C++ preprocessor, may it die, die, 
die!</rant>

>  I could add
> some version identifiers.

That would be one solution, but you'd have to create one version 
identifier for each target.

- Moritz


More information about the Digitalmars-d-announce mailing list