Page MenuHomePhabricator

[OCaml] Add LLVMInternalizePredicateBindings
Needs ReviewPublic

Authored by kren1 on Jul 23 2019, 3:49 AM.

Details

Reviewers
whitequark
CodaFi
Summary

This patch exposes the predicate API of internalize pass to OCaml.

Diff Detail

Event Timeline

kren1 created this revision.Jul 23 2019, 3:49 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 23 2019, 3:49 AM
whitequark added inline comments.Jul 23 2019, 4:09 AM
bindings/ocaml/transforms/ipo/llvm_ipo.mli
76

I don't think we make any claims of thread safety for any other API. Why a warning on this one?

kren1 marked an inline comment as done.Jul 23 2019, 4:39 AM
kren1 added inline comments.
bindings/ocaml/transforms/ipo/llvm_ipo.mli
76

I felt it's necessary to warn the user that the predicate is not passed by value, but its reference is stored in a global variable. This kind of seemed like the most concise way of saying that. Would you prefer it rephrased to more closely match the above or just removed?

whitequark added inline comments.Jul 23 2019, 4:48 AM
bindings/ocaml/transforms/ipo/llvm_ipo.mli
76

Wait. That's actually worse, because it's not *non-thread-safe*, it's not *reentrant*. Which probably doesn't matter for this specific function, but would be good to solve in general.

I haven't written any really complex OCaml/C interop code in a few years, so my skills here are a bit rusty... could you please look into a better way to do this? If not, no worries, I'll refresh my memory and dig into it myself, but it might take some weeks to get around to this.

kren1 updated this revision to Diff 211310.Jul 23 2019, 8:45 AM

Make add_internalize_predicate reentrant

kren1 marked an inline comment as done.Jul 23 2019, 8:50 AM
kren1 added inline comments.
bindings/ocaml/transforms/ipo/llvm_ipo.mli
76

I think I addressed this now. Cleaning up is a bit ugly, because I think the lifetime of the predicate closure should basically match the lifetime of the PassManager. I found no examples where this would be handled elsewhere. So I implemented a global association of PassManager and Predicate closure. When you dispose of the pass manager you walk the association and free all predicated associated with the pass manager being disposed.

Another option would be to extend the PassManager API and make it know about the closures associated with it, but I think this binding has little to do with the PassManager and should stay in its own directory.

whitequark added inline comments.Jul 23 2019, 9:14 AM
bindings/ocaml/transforms/ipo/llvm_ipo.mli
76

Thank you. Correct me if I'm wrong, but it looks like you could use OCaml APIs to maintain a linked list of predicates, and doing so would simplify the memory management here quite a bit, as well as make it more obviously sound.

kren1 marked an inline comment as done.Jul 24 2019, 2:02 AM
kren1 added inline comments.
bindings/ocaml/transforms/ipo/llvm_ipo.mli
76

You mean use caml_alloc and Store_field to construct an OCaml linked list in C? I could do that, but not sure it would be cleaner and more obviously sound. I find it easier to reason about C than what OCaml GC will be doing.

Another approach could be do to some mix-and-match of OCaml and C, for example deal with allocating and traversing the list in OCaml and then have C only allocate the contents of each list. That might work, but it would be spread over atleast 5 files and would require the Llvm_ipo to have a public ref exposed in its api (so that the PassManager can access it).

There is a similar problem in the first approach but there I could have an extern value* (similar to how I do it now).

Another way would be to find an implementation of linked-list in OCaml/LLVM C-api and then use that. That would be my preferred approach, but I couldn't find anything useable there (OCaml seems very GC orientated and LLVM has nothing). Do you have any pointers?

Let me know what would be the best way to proceed.

kren1 updated this revision to Diff 211717.Jul 25 2019, 4:59 AM
kren1 marked 3 inline comments as done.

Move most of the list handling stuff to OCaml

kren1 updated this revision to Diff 211895.Jul 26 2019, 2:10 AM

Fix the List.filter predicate