Generate code for if statements
authorLuke Lau <luke_lau@icloud.com>
Wed, 5 Jun 2019 21:31:04 +0000 (22:31 +0100)
committerLuke Lau <luke_lau@icloud.com>
Fri, 8 Nov 2019 15:07:39 +0000 (15:07 +0000)
commite3ba36b0fd73d28d041de61ed7d6bf590ef34f18
treec03756d00c68c7d673b5eade671a18597d4ea005
parent0d4ed473c520786af90ab70dac51451ea2b8b941
Generate code for if statements

Hopefully you found this addition straightforward and enjoyable, now
that we have all the infrastructure in place. Let's walk through this
step by step.

We first start off our loop by creating a basic block called "if". A
basic block is a chunk of code that has a single entry and exit point,
and in this block we're putting in the condition expression.
Since everything in Kaleidoscope is a double (yuck), we need to compare
it to zero to get a boolean that we can actually branch with.

After branching we create two other basic blocks labelled "then" and
"else", containing the then and else expressions of the branch
respectively. They both branch back to the final basic block, "ifcont".

Now since LLVM IR is in SSA (single static assignment) form, the then
and else branches both write to separate variables: We can't write to
the same variable twice. In order to actually differentiate between the
then expression and the else expression, we use a phi node in the merge
block. Depending on what basic block it arrived from, it will use either
one of two operands that we've passed to it.

In this case, we use it to return the then expression if the then branch
was taken, or the else expression if the else branch was taken. Phi
nodes are very common in LLVM IR, and open up lots of optimisations by
allowing us to stay in SSA form.

You might have also noticed that unlike the C++ tutorial, we didn't need
to rewind our builder back and generate the "mergeB" block first. In
fact, we actually end up referencing mergeB before it is even declared!
How can this be possible? Through recursive do! The MonadFix instance on
IRBuilder allow us to exploit laziness and use mdo to refer to variables
that haven't yet been evaluated.
Main.hs