From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id 891EB7EE25 for ; Tue, 5 Nov 2013 22:00:56 +0100 (CET) Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of nanaki@gmail.com) identity=pra; client-ip=209.85.128.180; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="nanaki@gmail.com"; x-sender="nanaki@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail2-smtp-roc.national.inria.fr: domain of nanaki@gmail.com designates 209.85.128.180 as permitted sender) identity=mailfrom; client-ip=209.85.128.180; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="nanaki@gmail.com"; x-sender="nanaki@gmail.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-ve0-f180.google.com) identity=helo; client-ip=209.85.128.180; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="nanaki@gmail.com"; x-sender="postmaster@mail-ve0-f180.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AlkOAB1ceVLRVYC0lGdsb2JhbABZgz9TgwiFbaNoihqHeEuBJAgWDgEBAQEHCwsJEiqCJQEBBAEgAwQZARsSCwEDAQsGAwILAwoNHQICIgERAQUBChIGEwgKCYdTAQMJBg2QSo9ai3kIA1ODCYQmChknAwpkiQEBBQyMdYJUBAeCaQKBRAOJQIlPhHuBL45uGCmCZoIMGw X-IPAS-Result: AlkOAB1ceVLRVYC0lGdsb2JhbABZgz9TgwiFbaNoihqHeEuBJAgWDgEBAQEHCwsJEiqCJQEBBAEgAwQZARsSCwEDAQsGAwILAwoNHQICIgERAQUBChIGEwgKCYdTAQMJBg2QSo9ai3kIA1ODCYQmChknAwpkiQEBBQyMdYJUBAeCaQKBRAOJQIlPhHuBL45uGCmCZoIMGw X-IronPort-AV: E=Sophos;i="4.93,641,1378850400"; d="scan'208";a="41098590" Received: from mail-ve0-f180.google.com ([209.85.128.180]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 05 Nov 2013 22:00:16 +0100 Received: by mail-ve0-f180.google.com with SMTP id oy12so2834989veb.25 for ; Tue, 05 Nov 2013 13:00:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=2Uki8fs0sod7teiCRI6hC2HuiCcHeAisZCb7hkQewik=; b=HCczsd5qdPbx5DNij2aP8J8WZZaXVeGSXLfdu6rFApPpZ751SsIYtlMMiKaqWCHe9v +zueV3SIIvkiF7412VHcju6eAPz2mwE9FDVDJXoqor7u+czvMFE+EDEv1NoZUyGBB7Uk W5DSYdSQqz00tzbD8Znm6Qa41cSIS4b/p//df1Bzb5mrInQ4rU/GGc7EZUW+BeqmGA8u GVonMctrrCVB6kLJO+qBgbK1DTRisiRxkxbj3SIHhfRVH+yWvwLApM2zEfI6XaSoX9RU YkEsN/N7Pz9NWBErJfHyZ+4ZKZ/GVcbEL5HNim/DhItV5l4j9glL6CVsjS5iFOwBs9aw a3LQ== MIME-Version: 1.0 X-Received: by 10.52.98.99 with SMTP id eh3mr5891620vdb.29.1383685250078; Tue, 05 Nov 2013 13:00:50 -0800 (PST) Received: by 10.58.220.135 with HTTP; Tue, 5 Nov 2013 13:00:50 -0800 (PST) In-Reply-To: <523e06f6b965a40b16bc8fe69a88e339@whitequark.org> References: <5278D1D1.4060009@gmail.com> <523e06f6b965a40b16bc8fe69a88e339@whitequark.org> Date: Tue, 5 Nov 2013 13:00:50 -0800 Message-ID: From: Jeff Meister To: Peter Zotov Cc: Caml List Content-Type: multipart/alternative; boundary=20cf307f3888cfe08604ea7453c8 Subject: Re: [Caml-list] LLVM OCaml bindings --20cf307f3888cfe08604ea7453c8 Content-Type: text/plain; charset=KOI8-R Content-Transfer-Encoding: quoted-printable Hi Peter, I did some work on the LLVM OCaml bindings back in grad school. Basically, I tried to fix the segfault issue that Jacques-Pascal mentioned above. The problem (well, one problem at least) is that LLVM's OCaml bindings operate through a C interface which is not type safe with respect to the underlying LLVM C++ implementation. For example, in llvm.mli we have: val const_int : lltype -> int -> llvalue val build_call : llvalue -> llvalue array -> string -> llbuilder -> llvalue I can call const_int to get an llvalue representing an integer, then pass this llvalue as the first argument to build_call, which expects a function. Since both have type llvalue, the OCaml type checker will not complain, but a segfault or other undefined behavior will likely result at runtime. What I did to fix this was reintroduce the inheritance hierarchy present in the C++ code. Using some module system tricks to make OCaml's structural subtyping act like nominal subtyping, I refactored everything into classes. In my version, const_int would return a ConstInt.t, which is a subtype of Value.t, but not compatible with the Function.t required by build_call. There are two reasons why I never publicly released my code. First, I haven't kept up with the last couple years of changes to the LLVM API, so it's probably not in a usable state right now. Second, OCaml subtyping is kind of a pain in the ass, and I wasn't sure whether people would want it. To pass a ConstInt.t into any method that expects a supertype requires an explicit cast, and the C++ structure of LLVM results in quite a lot of these casts. The cost of type-safe LLVM bindings is extra verbosity. However, there is a branch in the OCaml svn that would eliminate almost all of this cost: the implicit_subtyping branch. In that branch, if I'm passing a ConstInt.t to a function with a type annotation expecting Value.t, OCaml will try to perform the upcast for me, and proceed if it works. I played with this branch back when I was working on the bindings, and it made things much more pleasant. I'm not sure of the status of this branch, or whether the INRIA folks plan to integrate it into mainline at some point. I will try to find my code and put it up on GitHub if it would be useful to you. - Jeff On Tue, Nov 5, 2013 at 3:32 AM, Peter Zotov wrot= e: > Jacques-Pascal Deplaix =D0=C9=D3=C1=CC 05.11.2013 15:09: > >> Hi, >> >> >> So now I have again my own binding that produces LLVM-IR but this time >> with the same interface than the official binding, and it works pretty >> well [4]. >> > > The problem is that just generating LLVM IR is often not enough. > All of the below cannot be achieved without a proper binding: > > 1) JIT, > 2) Querying the backend for sizes of structures, legal integral types, > 3) Native code generation without shelling out. > > Generally, you can do very much with LLVM by shelling out to its plenthora > of command-line tools, but I find the in-process solution cleaner. > > You can get sensible error messages instead of segfaults by using > a Debug+Asserts or Release+Asserts build of LLVM. The builds packaged > in Debian, opam, etc are usually built without asserts. > > I'll probably release LLVM 3.4 bindings on opam and they will feature > asserts on by default. > > > [2]: I have done several issues on the LLVM bug tracker, but apart from >> segfaults and bugs when trying to use LLVM_bitwriter, the missed feature >> is, IMHO, the possibility to get a string that contains the LLVM-IR >> code, and not just print it. >> > > This will be included in upcoming 3.4 release. I will be happy to hear > (and likely implement) what else do you miss. > > > [3]: https://github.com/jpdeplaix/cervoise/blob/jeSuisFou/src/LLVM.mli >> [4]: https://github.com/jpdeplaix/cervoise/blob/master/src/LLVM.ml >> >> On 11/05/2013 05:23 AM, Peter Zotov wrote: >> >>> Hello folks, >>> >>> I'm currently working on improving LLVM's OCaml bindings. >>> There's been quite some progress so far[1]; the only major >>> areas pending are AOT code generation and MCJIT support. >>> >>> I would be very interested to hear how are you using these >>> bindings, or suggestions for future development. In particular, >>> I'd like to understand the impact of breaking the API. >>> >>> [1]: https://github.com/llvm-mirror/llvm/commits/master/bindings/ocaml >>> >>> > -- > WBR, Peter Zotov. > > > -- > Caml-list mailing list. Subscription management and archives: > https://sympa.inria.fr/sympa/arc/caml-list > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs > --20cf307f3888cfe08604ea7453c8 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Hi Peter,

I did some work = on the LLVM OCaml bindings back in grad school. Basically, I tried to fix t= he segfault issue that Jacques-Pascal mentioned above. The problem (well, o= ne problem at least) is that LLVM's OCaml bindings operate through a C = interface which is not type safe with respect to the underlying LLVM C++ im= plementation. For example, in llvm.mli we have:

val const_int : lltype -> int -> llvalue
val build_call : llva= lue -> llvalue array -> string -> llbuilder -> llvalue

<= /div>I can call const_int to get an llvalue representing an integer, then p= ass this llvalue as the first argument to build_call, which expects a funct= ion. Since both have type llvalue, the OCaml type checker will not complain= , but a segfault or other undefined behavior will likely result at runtime.=

What I did to fix this was reintroduce the inheritance hierarchy = present in the C++ code. Using some module system tricks to make OCaml'= s structural subtyping act like nominal subtyping, I refactored everything = into classes. In my version, const_int would return a ConstInt.t, which is = a subtype of Value.t, but not compatible with the Function.t required by bu= ild_call.

There are two reasons why I never publicly released my code. Firs= t, I haven't kept up with the last couple years of changes to the LLVM = API, so it's probably not in a usable state right now. Second, OCaml su= btyping is kind of a pain in the ass, and I wasn't sure whether people = would want it. To pass a ConstInt.t into any method that expects a supertyp= e requires an explicit cast, and the C++ structure of LLVM results in quite= a lot of these casts. The cost of type-safe LLVM bindings is extra verbosi= ty.

However, there is a branch in the OCaml svn that would eliminate almost= all of this cost: the implicit_subtyping branch. In that branch, if I'= m passing a ConstInt.t to a function with a type annotation expecting Value= .t, OCaml will try to perform the upcast for me, and proceed if it works. I= played with this branch back when I was working on the bindings, and it ma= de things much more pleasant. I'm not sure of the status of this branch= , or whether the INRIA folks plan to integrate it into mainline at some poi= nt.

I will try to find my code and put it up on GitHub if it would be= useful to you.

- Jeff

On Tue, Nov 5, 2013 at 3:32 AM, Peter Zotov= <whitequark@whitequark.org> wrote:
Jacques-Pascal Deplaix =D0=BF=D0=B8=D1=81=D0= =B0=D0=BB 05.11.2013 15:09:
Hi,


So now I have again my own binding that produces LLVM-IR but this time
with the same interface than the official binding, and it works pretty
well [4].

The problem is that just generating LLVM IR is often not enough.
All of the below cannot be achieved without a proper binding:

1) JIT,
2) Querying the backend for sizes of structures, legal integral types,
3) Native code generation without shelling out.

Generally, you can do very much with LLVM by shelling out to its plenthora<= br> of command-line tools, but I find the in-process solution cleaner.

You can get sensible error messages instead of segfaults by using
a Debug+Asserts or Release+Asserts build of LLVM. The builds packaged
in Debian, opam, etc are usually built without asserts.

I'll probably release LLVM 3.4 bindings on opam and they will feature asserts on by default.


[2]: I have done several issues on the LLVM bug tracker, but apart from
segfaults and bugs when trying to use LLVM_bitwriter, the missed feature
is, IMHO, the possibility to get a string that contains the LLVM-IR
code, and not just print it.

This will be included in upcoming 3.4 release. I will be happy to hear
(and likely implement) what else do you miss.


[3]: https://github.com/jpdeplaix/cervoise/blob= /jeSuisFou/src/LLVM.mli
[4]: https://github.com/jpdeplaix/cervoise/blob/mas= ter/src/LLVM.ml

On 11/05/2013 05:23 AM, Peter Zotov wrote:
Hello folks,

I'm currently working on improving LLVM's OCaml bindings.
There's been quite some progress so far[1]; the only major
areas pending are AOT code generation and MCJIT support.

I would be very interested to hear how are you using these
bindings, or suggestions for future development. In particular,
I'd like to understand the impact of breaking the API.

=C2=A0 [1]: https://github.com/llvm-mirror/llvm= /commits/master/bindings/ocaml


--
=C2=A0 WBR, Peter Zotov.

--20cf307f3888cfe08604ea7453c8--