Hi, I'm trying to understand how can I use Cranelift to execute Prolog code efficiently. In Scryer Prolog, we have a WAM-compiler (Prolog -> WAM) and a WAM (Warren Abstract Machine) implemented in Rust in a simple way. We have code in a Vec, we have a variable for each machine register, and we iterate using a PC variable to know which instruction execute next. We think, that by using Cranelift we can improve the performance of it, but I have several doubts.
First one, is when to do the compilation. The system starts very early with Prolog, and then you start loading modules, introducing code in the REPL and asserting new predicates. What should be the best moment to do the JIT? When a new module is loaded (have one JITModule per Module), as soon as a new predicate is found (have one JITModule per predicate), every time it changes compile everything again (have one JITModule for everything?).
Second question, how to do the compilation of code that calls undefined predicates. This is not a semantic error in Prolog (they should issue an exception but only when you arrive at it). You can define the predicate later for example and fix the problem. But to do a call, it seems like you need to have a defined symbol.
Three, how to organize functions. My idea is that every Prolog predicate can be mapped to an IR function that takes N arguments as the N arity of the predicate. Prolog predicates can have up to 1024 arity. So 1024 arguments in the signature. Then, there are some machine state variables that I need to keep track. I was thinking of passing that as a pointer to the data section, but I'm not sure if I'm proposing something crazy.
Thanks for your patience!
Last updated: Nov 22 2024 at 16:03 UTC