Stream: compiler development

Topic: bf interpreter analysis


view this post on Zulip Ayaz Hafiz (Jul 18 2023 at 20:00):

Looking at #beginners > Help optimising my BF interpreter - a few things I think we should be able to address hopefully easily

  1. the tokinizer step compiles to a very poor if/else chain rather than a switch (https://gist.github.com/ayazhafiz/9669cbf36cf33001f794a0cab4db95f5). I think we should be able to eliminate the decs on constant strings here as well (https://github.com/roc-lang/roc/issues/5594)

view this post on Zulip Ayaz Hafiz (Jul 18 2023 at 20:02):

looking at the compilation of run: https://gist.github.com/ayazhafiz/edfb055da1082f8f42f352846222bd3e
I think we would benefit strongly from even naive LICM, escape analysis, and inline passes. If we inline List.get and run LICM we should be able to see that Interpreter.221 can be hoisted outside the joinpoint, needs no inc, and the bounds check can be hoisted as well

view this post on Zulip Qqwy / Marten (Jul 18 2023 at 20:30):

The interpreter is currently written in an indirect-threaded/subroutine-threaded style rather than in a direct-threaded style.

Or at least the compiled code looks this way (every branch has its own call to goToNextCommand)

I wonder whether the performance of a version of the code where goToNextCommand |> run is moved outside of the whenis different or not. An inlining or duplicate code removal pass would do that automatically.

view this post on Zulip Qqwy / Marten (Jul 18 2023 at 20:51):

Folkert asked about the different ways blocks (the BF equivalent of loops) are implemented in various BF interpreters.
I had to refresh my memory on it, but seems like the main two ways are (according to a brief skimming of RosettaCode):

I have not seen the technique of turning the BF AST into a tree before or elsewhere, though it is of course a very popular approach when interpreting any more complicated language :D


Last updated: Jul 06 2025 at 12:14 UTC