[LLVMdev] OCaml bindings
Gordon Henriksen
gordonhenriksen at mac.com
Sun Nov 25 12:01:53 PST 2007
On Nov 25, 2007, at 11:49, Jon Harrop wrote:
> On Sunday 25 November 2007 12:23, Gordon Henriksen wrote:
>
>> If ocamlc is on your path, then 'configure; make; make install'
>> should install the bindings in your ocaml lib.
>
> Right. I hadn't noticed they were already installed after llvm "make
> install" in:
>
> /usr/local/lib/ocaml/
Right. They're installed in 'if $stdlib is beneath $prefix then
$stdlib else $prefix/lib/ocaml'. :) You can force the matter with
./configure --with-ocaml-libdir=`ocamlc -where`
>> On 2007-11-24, at 21:58, Jon Harrop wrote:
>>
>>
>>> - Some interface to LLVM from OCaml
>>> What is the easiest way to interface a front-end written in OCaml
>>> with an LLVM backend?
>>
>> The C and Ocaml bindings in the source tree are intended to cover
>> precisely this scenario, and I would recommend them over .ll
>> emission. Jan's remark is a bit out of date; the bindings are
>> sufficient for code generation now. A few corners of the IR are
>> still not fully covered, but extending the bindings to new methods
>> is quite straightforward.
>>
>>> I just rediscovered the OCaml bindings in bindings/ocaml (...).
>>> They do indeed look quite complete but I can't find any examples
>>> using them.
>>
>> See an example here, which an Ocaml program to emit the bitcode for
>> a "hello world" program:
>>
>> http://lists.cs.uiuc.edu/pipermail/llvmdev/2007-October/010996.html
>>
>
> Wow, this is just great!
>
> I had to tweak your example to get it to compile. Some of the
> function names and signatures have changed (I'm using CVS LLVM) so
> I've updated them and just thrown away the booleans you were passing
> (no idea what they were for but it works ;-).
Ah, right; I'd forgotten about those changes or I would've updated it
for you. The booleans in particular were used for null-terminating
strings and creating varargs function types, among others, but weren't
self-documenting, so I introduced variant names instead. For instance:
> Also, I think const_string maybe should null terminate the given
> string so I changed your example to pass it a null terminated string
> instead (nasty hack).
const_stringz null-terminates the string. But adding \000 in the
literal as you did is equivalent.
> My code is:
>
> [...]
>
> To use it I just do:
>
> $ ocamlopt -dtypes -cc g++ -I /usr/local/lib/ocaml/ llvm.cmxa
> llvm_bitwriter.cmxa hellow.ml -o hellow
> $ ./hellow run.bc
>
> How do I compile straight to native code without going via C?
-march=c invokes a very unusual LLVM target which emits C code instead
of assembly. Read http://llvm.org/cmds/llc.html and llc --help. Here:
> $ llc -f -march=c run.bc -o run.c
Simply run 'llc run.bc -o run.s' to generate native assembly code.
From there, you can use 'as' and 'ld' to assemble and link.
In my example, I had used the gcc driver to succinctly invoke 'as' and
'ld' in the proper platform-specific manner, including linking with
the C standard library (for printf). Since the input was already
compiled to assembly code, 'gcc' did not invoke the C compiler.
> $ gcc run.c -o run
> run.c:114: warning: conflicting types for built-in function ‘malloc’
> run.c: In function ‘main’:
> run.c:143: warning: return type of ‘main’ is not ‘int’
> $ ./run
> Hello, world!
>
> Can we use pipes to avoid generating intermediate files?
For the llvm tools, yes. For instance:
# optimize bitcode and disassemble to LLVM assembly
opt -std-compile-opts < run.bc | llvm-dis
# optimize bitcode, compile to native assembly, and assemble to
native object
opt -std-compile-opts < run.bc | llc | as -o run.o
However, writing the bitcode presently requires a temp file. This is a
problem with the libraries at both ends:
1. Standard C++ doesn't provide file-descriptor streams at all.
(LLVM uses C++ iostreams.)
2. Ocaml doesn't allow extracting the file descriptor from an
Output_channel.
There are a variety of workarounds available for the bindings, but I
have not yet pursued them. The simplest is a "write_bitcode_to_stdout"
function which uses the std::cout stream internally.
>> I think a translation of the tutorial would be most welcome and
>> about 10x shorter. ;-)
>
> Shall we port the tutorial to OCaml?
By all means! I think you'd also stumble across some areas that are
not bound yet, such as building pipelines to run optimizations in-
process. I'd be happy to fill in any gaps you find. It would be a very
useful exercise in that it would generate that feedback, improving
both the C and Ocaml bindings.
You'll find that the LLVM community openly welcomes not only users and
their contributions, so please jump in and get your hands dirty. The
#llvm IRC channel on irc.oftc.net is also a great resource.
— Gordon
More information about the llvm-dev
mailing list