Hello! As I mentioned in What is the status of SWI-Prolog ported to WebAssembly, I’m working on enhancing swipl’s WebAssembly port. It’s going along fairly well, with the one unfortunate exception that pl-wam.c takes approximately 180 seconds to compile, and it won’t even run (PL_next_solution()
gives a runtime error: "Too many local variables"
) when compiled at -O0.
So I’ve started down a separate path of refactoring the WAM code away from the one-big-function paradigm and towards one-function-per-instruction. My thought is to kill two birds with one stone - to allow compilation on WASM regardless of optimization level, but also to make the control/data flow more explicit, to give modern compilers more of a chance to optimize.
Initial results are promising - I have a prototype function-mode build (currently compiling to native Linux/64/gcc), and there’s no noticeable performance difference between that and either the switch-mode or goto-mode builds: the ctest suite passes all tests, and it takes close enough to exactly the same amount of time in each mode that I’d probably need to average out over a couple-hundred runs just to tell which was fastest. Is there a better benchmarking test that I can run?
Core devs, especially @jan - what are your thoughts on this move? Should it be restricted to the WASM build? If it proves to be as performant as the single-function version, should the old version be removed entirely given the clutter it requires in PL_next_solution()
? Should it go even further? I can already think of some potential mechanisms that this model would enable, including the possibility to precompile sequences of WAM bytecodes to C, perhaps even whole procedures, with full optimization.