=======================================================
Kaleidoscope: Extending the Language: Mutable Variables
=======================================================

.. contents::
   :local:

Chapter 7 Introduction
======================

Welcome to Chapter 7 of the "`Implementing a language with
LLVM <index.html>`_" tutorial. In chapters 1 through 6, we've built a
very respectable, albeit simple, `functional programming
language <http://en.wikipedia.org/wiki/Functional_programming>`_. In our
journey, we learned some parsing techniques, how to build and represent
an AST, how to build LLVM IR, and how to optimize the resultant code as
well as JIT compile it.

While Kaleidoscope is interesting as a functional language, the fact
that it is functional makes it "too easy" to generate LLVM IR for it. In
particular, a functional language makes it very easy to build LLVM IR
directly in `SSA
form <http://en.wikipedia.org/wiki/Static_single_assignment_form>`_.
Since LLVM requires that the input code be in SSA form, this is a very
nice property and it is often unclear to newcomers how to generate code
for an imperative language with mutable variables.

The short (and happy) summary of this chapter is that there is no need
for your front-end to build SSA form: LLVM provides highly tuned and
well tested support for this, though the way it works is a bit
unexpected for some.

Why is this a hard problem?
===========================

To understand why mutable variables cause complexities in SSA
construction, consider this extremely simple C example:

.. code-block:: c

    int G, H;
    int test(_Bool Condition) {
      int X;
      if (Condition)
        X = G;
      else
        X = H;
      return X;
    }

In this case, we have the variable "X", whose value depends on the path
executed in the program. Because there are two different possible values
for X before the return instruction, a PHI node is inserted to merge the
two values. The LLVM IR that we want for this example looks like this:

.. code-block:: llvm

    @G = weak global i32 0   ; type of @G is i32*
    @H = weak global i32 0   ; type of @H is i32*

    define i32 @test(i1 %Condition) {
    entry:
      br i1 %Condition, label %cond_true, label %cond_false

    cond_true:
      %X.0 = load i32* @G
      br label %cond_next

    cond_false:
      %X.1 = load i32* @H
      br label %cond_next

    cond_next:
      %X.2 = phi i32 [ %X.1, %cond_false ], [ %X.0, %cond_true ]
      ret i32 %X.2
    }

In this example, the loads from the G and H global variables are
explicit in the LLVM IR, and they live in the then/else branches of the
if statement (cond\_true/cond\_false). In order to merge the incoming
values, the X.2 phi node in the cond\_next block selects the right value
to use based on where control flow is coming from: if control flow comes
from the cond\_false block, X.2 gets the value of X.1. Alternatively, if
control flow comes from cond\_true, it gets the value of X.0. The intent
of this chapter is not to explain the details of SSA form. For more
information, see one of the many `online
references <http://en.wikipedia.org/wiki/Static_single_assignment_form>`_.

The question for this article is "who places the phi nodes when lowering
assignments to mutable variables?". The issue here is that LLVM
*requires* that its IR be in SSA form: there is no "non-ssa" mode for
it. However, SSA construction requires non-trivial algorithms and data
structures, so it is inconvenient and wasteful for every front-end to
have to reproduce this logic.

Memory in LLVM
==============

The 'trick' here is that while LLVM does require all register values to
be in SSA form, it does not require (or permit) memory objects to be in
SSA form. In the example above, note that the loads from G and H are
direct accesses to G and H: they are not renamed or versioned. This
differs from some other compiler systems, which do try to version memory
objects. In LLVM, instead of encoding dataflow analysis of memory into
the LLVM IR, it is handled with `Analysis
Passes <../WritingAnLLVMPass.html>`_ which are computed on demand.

With this in mind, the high-level idea is that we want to make a stack
variable (which lives in memory, because it is on the stack) for each
mutable object in a function. To take advantage of this trick, we need
to talk about how LLVM represents stack variables.

In LLVM, all memory accesses are explicit with load/store instructions,
and it is carefully designed not to have (or need) an "address-of"
operator. Notice how the type of the @G/@H global variables is actually
"i32\*" even though the variable is defined as "i32". What this means is
that @G defines *space* for an i32 in the global data area, but its
*name* actually refers to the address for that space. Stack variables
work the same way, except that instead of being declared with global
variable definitions, they are declared with the `LLVM alloca
instruction <../LangRef.html#alloca-instruction>`_:

.. code-block:: llvm

    define i32 @example() {
    entry:
      %X = alloca i32           ; type of %X is i32*.
      ...
      %tmp = load i32* %X       ; load the stack value %X from the stack.
      %tmp2 = add i32 %tmp, 1   ; increment it
      store i32 %tmp2, i32* %X  ; store it back
      ...

This code shows an example of how you can declare and manipulate a stack
variable in the LLVM IR. Stack memory allocated with the alloca
instruction is fully general: you can pass the address of the stack slot
to functions, you can store it in other variables, etc. In our example
above, we could rewrite the example to use the alloca technique to avoid
using a PHI node:

.. code-block:: llvm

    @G = weak global i32 0   ; type of @G is i32*
    @H = weak global i32 0   ; type of @H is i32*

    define i32 @test(i1 %Condition) {
    entry:
      %X = alloca i32           ; type of %X is i32*.
      br i1 %Condition, label %cond_true, label %cond_false

    cond_true:
      %X.0 = load i32* @G
            store i32 %X.0, i32* %X   ; Update X
      br label %cond_next

    cond_false:
      %X.1 = load i32* @H
            store i32 %X.1, i32* %X   ; Update X
      br label %cond_next

    cond_next:
      %X.2 = load i32* %X       ; Read X
      ret i32 %X.2
    }

With this, we have discovered a way to handle arbitrary mutable
variables without the need to create Phi nodes at all:

#. Each mutable variable becomes a stack allocation.
#. Each read of the variable becomes a load from the stack.
#. Each update of the variable becomes a store to the stack.
#. Taking the address of a variable just uses the stack address
   directly.

While this solution has solved our immediate problem, it introduced
another one: we have now apparently introduced a lot of stack traffic
for very simple and common operations, a major performance problem.
Fortunately for us, the LLVM optimizer has a highly-tuned optimization
pass named "mem2reg" that handles this case, promoting allocas like this
into SSA registers, inserting Phi nodes as appropriate. If you run this
example through the pass, for example, you'll get:

.. code-block:: bash

    $ llvm-as < example.ll | opt -mem2reg | llvm-dis
    @G = weak global i32 0
    @H = weak global i32 0

    define i32 @test(i1 %Condition) {
    entry:
      br i1 %Condition, label %cond_true, label %cond_false

    cond_true:
      %X.0 = load i32* @G
      br label %cond_next

    cond_false:
      %X.1 = load i32* @H
      br label %cond_next

    cond_next:
      %X.01 = phi i32 [ %X.1, %cond_false ], [ %X.0, %cond_true ]
      ret i32 %X.01
    }

The mem2reg pass implements the standard "iterated dominance frontier"
algorithm for constructing SSA form and has a number of optimizations
that speed up (very common) degenerate cases. The mem2reg optimization
pass is the answer to dealing with mutable variables, and we highly
recommend that you depend on it. Note that mem2reg only works on
variables in certain circumstances:

#. mem2reg is alloca-driven: it looks for allocas and if it can handle
   them, it promotes them. It does not apply to global variables or heap
   allocations.
#. mem2reg only looks for alloca instructions in the entry block of the
   function. Being in the entry block guarantees that the alloca is only
   executed once, which makes analysis simpler.
#. mem2reg only promotes allocas whose uses are direct loads and stores.
   If the address of the stack object is passed to a function, or if any
   funny pointer arithmetic is involved, the alloca will not be
   promoted.
#. mem2reg only works on allocas of `first
   class <../LangRef.html#first-class-types>`_ values (such as pointers,
   scalars and vectors), and only if the array size of the allocation is
   1 (or missing in the .ll file). mem2reg is not capable of promoting
   structs or arrays to registers. Note that the "sroa" pass is
   more powerful and can promote structs, "unions", and arrays in many
   cases.

All of these properties are easy to satisfy for most imperative
languages, and we'll illustrate it below with Kaleidoscope. The final
question you may be asking is: should I bother with this nonsense for my
front-end? Wouldn't it be better if I just did SSA construction
directly, avoiding use of the mem2reg optimization pass? In short, we
strongly recommend that you use this technique for building SSA form,
unless there is an extremely good reason not to. Using this technique
is:

-  Proven and well tested: clang uses this technique
   for local mutable variables. As such, the most common clients of LLVM
   are using this to handle a bulk of their variables. You can be sure
   that bugs are found fast and fixed early.
-  Extremely Fast: mem2reg has a number of special cases that make it
   fast in common cases as well as fully general. For example, it has
   fast-paths for variables that are only used in a single block,
   variables that only have one assignment point, good heuristics to
   avoid insertion of unneeded phi nodes, etc.
-  Needed for debug info generation: `Debug information in
   LLVM <../SourceLevelDebugging.html>`_ relies on having the address of
   the variable exposed so that debug info can be attached to it. This
   technique dovetails very naturally with this style of debug info.

If nothing else, this makes it much easier to get your front-end up and
running, and is very simple to implement. Lets extend Kaleidoscope with
mutable variables now!

Mutable Variables in Kaleidoscope
=================================

Now that we know the sort of problem we want to tackle, lets see what
this looks like in the context of our little Kaleidoscope language.
We're going to add two features:

#. The ability to mutate variables with the '=' operator.
#. The ability to define new variables.

While the first item is really what this is about, we only have
variables for incoming arguments as well as for induction variables, and
redefining those only goes so far :). Also, the ability to define new
variables is a useful thing regardless of whether you will be mutating
them. Here's a motivating example that shows how we could use these:

::

    # Define ':' for sequencing: as a low-precedence operator that ignores operands
    # and just returns the RHS.
    def binary : 1 (x y) y;

    # Recursive fib, we could do this before.
    def fib(x)
      if (x < 3) then
        1
      else
        fib(x-1)+fib(x-2);

    # Iterative fib.
    def fibi(x)
      var a = 1, b = 1, c in
      (for i = 3, i < x in
         c = a + b :
         a = b :
         b = c) :
      b;

    # Call it.
    fibi(10);

In order to mutate variables, we have to change our existing variables
to use the "alloca trick". Once we have that, we'll add our new
operator, then extend Kaleidoscope to support new variable definitions.

Adjusting Existing Variables for Mutation
=========================================

The symbol table in Kaleidoscope is managed at code generation time by
the '``named_values``' map. This map currently keeps track of the LLVM
"Value\*" that holds the double value for the named variable. In order
to support mutation, we need to change this slightly, so that it
``named_values`` holds the *memory location* of the variable in
question. Note that this change is a refactoring: it changes the
structure of the code, but does not (by itself) change the behavior of
the compiler. All of these changes are isolated in the Kaleidoscope code
generator.

At this point in Kaleidoscope's development, it only supports variables
for two things: incoming arguments to functions and the induction
variable of 'for' loops. For consistency, we'll allow mutation of these
variables in addition to other user-defined variables. This means that
these will both need memory locations.

To start our transformation of Kaleidoscope, we'll change the
``named_values`` map so that it maps to AllocaInst\* instead of Value\*.
Once we do this, the C++ compiler will tell us what parts of the code we
need to update:

**Note:** the ocaml bindings currently model both ``Value*``'s and
``AllocInst*``'s as ``Llvm.llvalue``'s, but this may change in the future
to be more type safe.

.. code-block:: ocaml

    let named_values:(string, llvalue) Hashtbl.t = Hashtbl.create 10

Also, since we will need to create these alloca's, we'll use a helper
function that ensures that the allocas are created in the entry block of
the function:

.. code-block:: ocaml

    (* Create an alloca instruction in the entry block of the function. This
     * is used for mutable variables etc. *)
    let create_entry_block_alloca the_function var_name =
      let builder = builder_at (instr_begin (entry_block the_function)) in
      build_alloca double_type var_name builder

This funny looking code creates an ``Llvm.llbuilder`` object that is
pointing at the first instruction of the entry block. It then creates an
alloca with the expected name and returns it. Because all values in
Kaleidoscope are doubles, there is no need to pass in a type to use.

With this in place, the first functionality change we want to make is to
variable references. In our new scheme, variables live on the stack, so
code generating a reference to them actually needs to produce a load
from the stack slot:

.. code-block:: ocaml

    let rec codegen_expr = function
      ...
      | Ast.Variable name ->
          let v = try Hashtbl.find named_values name with
            | Not_found -> raise (Error "unknown variable name")
          in
          (* Load the value. *)
          build_load v name builder

As you can see, this is pretty straightforward. Now we need to update
the things that define the variables to set up the alloca. We'll start
with ``codegen_expr Ast.For ...`` (see the `full code listing <#id1>`_
for the unabridged code):

.. code-block:: ocaml

      | Ast.For (var_name, start, end_, step, body) ->
          let the_function = block_parent (insertion_block builder) in

          (* Create an alloca for the variable in the entry block. *)
          let alloca = create_entry_block_alloca the_function var_name in

          (* Emit the start code first, without 'variable' in scope. *)
          let start_val = codegen_expr start in

          (* Store the value into the alloca. *)
          ignore(build_store start_val alloca builder);

          ...

          (* Within the loop, the variable is defined equal to the PHI node. If it
           * shadows an existing variable, we have to restore it, so save it
           * now. *)
          let old_val =
            try Some (Hashtbl.find named_values var_name) with Not_found -> None
          in
          Hashtbl.add named_values var_name alloca;

          ...

          (* Compute the end condition. *)
          let end_cond = codegen_expr end_ in

          (* Reload, increment, and restore the alloca. This handles the case where
           * the body of the loop mutates the variable. *)
          let cur_var = build_load alloca var_name builder in
          let next_var = build_add cur_var step_val "nextvar" builder in
          ignore(build_store next_var alloca builder);
          ...

This code is virtually identical to the code `before we allowed mutable
variables <OCamlLangImpl5.html#code-generation-for-the-for-loop>`_. The big difference is that
we no longer have to construct a PHI node, and we use load/store to
access the variable as needed.

To support mutable argument variables, we need to also make allocas for
them. The code for this is also pretty simple:

.. code-block:: ocaml

    (* Create an alloca for each argument and register the argument in the symbol
     * table so that references to it will succeed. *)
    let create_argument_allocas the_function proto =
      let args = match proto with
        | Ast.Prototype (_, args) | Ast.BinOpPrototype (_, args, _) -> args
      in
      Array.iteri (fun i ai ->
        let var_name = args.(i) in
        (* Create an alloca for this variable. *)
        let alloca = create_entry_block_alloca the_function var_name in

        (* Store the initial value into the alloca. *)
        ignore(build_store ai alloca builder);

        (* Add arguments to variable symbol table. *)
        Hashtbl.add named_values var_name alloca;
      ) (params the_function)

For each argument, we make an alloca, store the input value to the
function into the alloca, and register the alloca as the memory location
for the argument. This method gets invoked by ``Codegen.codegen_func``
right after it sets up the entry block for the function.

The final missing piece is adding the mem2reg pass, which allows us to
get good codegen once again:

.. code-block:: ocaml

    let main () =
      ...
      let the_fpm = PassManager.create_function Codegen.the_module in

      (* Set up the optimizer pipeline.  Start with registering info about how the
       * target lays out data structures. *)
      DataLayout.add (ExecutionEngine.target_data the_execution_engine) the_fpm;

      (* Promote allocas to registers. *)
      add_memory_to_register_promotion the_fpm;

      (* Do simple "peephole" optimizations and bit-twiddling optzn. *)
      add_instruction_combining the_fpm;

      (* reassociate expressions. *)
      add_reassociation the_fpm;

It is interesting to see what the code looks like before and after the
mem2reg optimization runs. For example, this is the before/after code
for our recursive fib function. Before the optimization:

.. code-block:: llvm

    define double @fib(double %x) {
    entry:
      %x1 = alloca double
      store double %x, double* %x1
      %x2 = load double* %x1
      %cmptmp = fcmp ult double %x2, 3.000000e+00
      %booltmp = uitofp i1 %cmptmp to double
      %ifcond = fcmp one double %booltmp, 0.000000e+00
      br i1 %ifcond, label %then, label %else

    then:    ; preds = %entry
      br label %ifcont

    else:    ; preds = %entry
      %x3 = load double* %x1
      %subtmp = fsub double %x3, 1.000000e+00
      %calltmp = call double @fib(double %subtmp)
      %x4 = load double* %x1
      %subtmp5 = fsub double %x4, 2.000000e+00
      %calltmp6 = call double @fib(double %subtmp5)
      %addtmp = fadd double %calltmp, %calltmp6
      br label %ifcont

    ifcont:    ; preds = %else, %then
      %iftmp = phi double [ 1.000000e+00, %then ], [ %addtmp, %else ]
      ret double %iftmp
    }

Here there is only one variable (x, the input argument) but you can
still see the extremely simple-minded code generation strategy we are
using. In the entry block, an alloca is created, and the initial input
value is stored into it. Each reference to the variable does a reload
from the stack. Also, note that we didn't modify the if/then/else
expression, so it still inserts a PHI node. While we could make an
alloca for it, it is actually easier to create a PHI node for it, so we
still just make the PHI.

Here is the code after the mem2reg pass runs:

.. code-block:: llvm

    define double @fib(double %x) {
    entry:
      %cmptmp = fcmp ult double %x, 3.000000e+00
      %booltmp = uitofp i1 %cmptmp to double
      %ifcond = fcmp one double %booltmp, 0.000000e+00
      br i1 %ifcond, label %then, label %else

    then:
      br label %ifcont

    else:
      %subtmp = fsub double %x, 1.000000e+00
      %calltmp = call double @fib(double %subtmp)
      %subtmp5 = fsub double %x, 2.000000e+00
      %calltmp6 = call double @fib(double %subtmp5)
      %addtmp = fadd double %calltmp, %calltmp6
      br label %ifcont

    ifcont:    ; preds = %else, %then
      %iftmp = phi double [ 1.000000e+00, %then ], [ %addtmp, %else ]
      ret double %iftmp
    }

This is a trivial case for mem2reg, since there are no redefinitions of
the variable. The point of showing this is to calm your tension about
inserting such blatent inefficiencies :).

After the rest of the optimizers run, we get:

.. code-block:: llvm

    define double @fib(double %x) {
    entry:
      %cmptmp = fcmp ult double %x, 3.000000e+00
      %booltmp = uitofp i1 %cmptmp to double
      %ifcond = fcmp ueq double %booltmp, 0.000000e+00
      br i1 %ifcond, label %else, label %ifcont

    else:
      %subtmp = fsub double %x, 1.000000e+00
      %calltmp = call double @fib(double %subtmp)
      %subtmp5 = fsub double %x, 2.000000e+00
      %calltmp6 = call double @fib(double %subtmp5)
      %addtmp = fadd double %calltmp, %calltmp6
      ret double %addtmp

    ifcont:
      ret double 1.000000e+00
    }

Here we see that the simplifycfg pass decided to clone the return
instruction into the end of the 'else' block. This allowed it to
eliminate some branches and the PHI node.

Now that all symbol table references are updated to use stack variables,
we'll add the assignment operator.

New Assignment Operator
=======================

With our current framework, adding a new assignment operator is really
simple. We will parse it just like any other binary operator, but handle
it internally (instead of allowing the user to define it). The first
step is to set a precedence:

.. code-block:: ocaml

    let main () =
      (* Install standard binary operators.
       * 1 is the lowest precedence. *)
      Hashtbl.add Parser.binop_precedence '=' 2;
      Hashtbl.add Parser.binop_precedence '<' 10;
      Hashtbl.add Parser.binop_precedence '+' 20;
      Hashtbl.add Parser.binop_precedence '-' 20;
      ...

Now that the parser knows the precedence of the binary operator, it
takes care of all the parsing and AST generation. We just need to
implement codegen for the assignment operator. This looks like:

.. code-block:: ocaml

    let rec codegen_expr = function
          begin match op with
          | '=' ->
              (* Special case '=' because we don't want to emit the LHS as an
               * expression. *)
              let name =
                match lhs with
                | Ast.Variable name -> name
                | _ -> raise (Error "destination of '=' must be a variable")
              in

Unlike the rest of the binary operators, our assignment operator doesn't
follow the "emit LHS, emit RHS, do computation" model. As such, it is
handled as a special case before the other binary operators are handled.
The other strange thing is that it requires the LHS to be a variable. It
is invalid to have "(x+1) = expr" - only things like "x = expr" are
allowed.

.. code-block:: ocaml

              (* Codegen the rhs. *)
              let val_ = codegen_expr rhs in

              (* Lookup the name. *)
              let variable = try Hashtbl.find named_values name with
              | Not_found -> raise (Error "unknown variable name")
              in
              ignore(build_store val_ variable builder);
              val_
          | _ ->
                ...

Once we have the variable, codegen'ing the assignment is
straightforward: we emit the RHS of the assignment, create a store, and
return the computed value. Returning a value allows for chained
assignments like "X = (Y = Z)".

Now that we have an assignment operator, we can mutate loop variables
and arguments. For example, we can now run code like this:

::

    # Function to print a double.
    extern printd(x);

    # Define ':' for sequencing: as a low-precedence operator that ignores operands
    # and just returns the RHS.
    def binary : 1 (x y) y;

    def test(x)
      printd(x) :
      x = 4 :
      printd(x);

    test(123);

When run, this example prints "123" and then "4", showing that we did
actually mutate the value! Okay, we have now officially implemented our
goal: getting this to work requires SSA construction in the general
case. However, to be really useful, we want the ability to define our
own local variables, lets add this next!

User-defined Local Variables
============================

Adding var/in is just like any other other extensions we made to
Kaleidoscope: we extend the lexer, the parser, the AST and the code
generator. The first step for adding our new 'var/in' construct is to
extend the lexer. As before, this is pretty trivial, the code looks like
this:

.. code-block:: ocaml

    type token =
      ...
      (* var definition *)
      | Var

    ...

    and lex_ident buffer = parser
          ...
          | "in" -> [< 'Token.In; stream >]
          | "binary" -> [< 'Token.Binary; stream >]
          | "unary" -> [< 'Token.Unary; stream >]
          | "var" -> [< 'Token.Var; stream >]
          ...

The next step is to define the AST node that we will construct. For
var/in, it looks like this:

.. code-block:: ocaml

    type expr =
      ...
      (* variant for var/in. *)
      | Var of (string * expr option) array * expr
      ...

var/in allows a list of names to be defined all at once, and each name
can optionally have an initializer value. As such, we capture this
information in the VarNames vector. Also, var/in has a body, this body
is allowed to access the variables defined by the var/in.

With this in place, we can define the parser pieces. The first thing we
do is add it as a primary expression:

.. code-block:: ocaml

    (* primary
     *   ::= identifier
     *   ::= numberexpr
     *   ::= parenexpr
     *   ::= ifexpr
     *   ::= forexpr
     *   ::= varexpr *)
    let rec parse_primary = parser
      ...
      (* varexpr
       *   ::= 'var' identifier ('=' expression?
       *             (',' identifier ('=' expression)?)* 'in' expression *)
      | [< 'Token.Var;
           (* At least one variable name is required. *)
           'Token.Ident id ?? "expected identifier after var";
           init=parse_var_init;
           var_names=parse_var_names [(id, init)];
           (* At this point, we have to have 'in'. *)
           'Token.In ?? "expected 'in' keyword after 'var'";
           body=parse_expr >] ->
          Ast.Var (Array.of_list (List.rev var_names), body)

    ...

    and parse_var_init = parser
      (* read in the optional initializer. *)
      | [< 'Token.Kwd '='; e=parse_expr >] -> Some e
      | [< >] -> None

    and parse_var_names accumulator = parser
      | [< 'Token.Kwd ',';
           'Token.Ident id ?? "expected identifier list after var";
           init=parse_var_init;
           e=parse_var_names ((id, init) :: accumulator) >] -> e
      | [< >] -> accumulator

Now that we can parse and represent the code, we need to support
emission of LLVM IR for it. This code starts out with:

.. code-block:: ocaml

    let rec codegen_expr = function
      ...
      | Ast.Var (var_names, body)
          let old_bindings = ref [] in

          let the_function = block_parent (insertion_block builder) in

          (* Register all variables and emit their initializer. *)
          Array.iter (fun (var_name, init) ->

Basically it loops over all the variables, installing them one at a
time. For each variable we put into the symbol table, we remember the
previous value that we replace in OldBindings.

.. code-block:: ocaml

            (* Emit the initializer before adding the variable to scope, this
             * prevents the initializer from referencing the variable itself, and
             * permits stuff like this:
             *   var a = 1 in
             *     var a = a in ...   # refers to outer 'a'. *)
            let init_val =
              match init with
              | Some init -> codegen_expr init
              (* If not specified, use 0.0. *)
              | None -> const_float double_type 0.0
            in

            let alloca = create_entry_block_alloca the_function var_name in
            ignore(build_store init_val alloca builder);

            (* Remember the old variable binding so that we can restore the binding
             * when we unrecurse. *)

            begin
              try
                let old_value = Hashtbl.find named_values var_name in
                old_bindings := (var_name, old_value) :: !old_bindings;
              with Not_found > ()
            end;

            (* Remember this binding. *)
            Hashtbl.add named_values var_name alloca;
          ) var_names;

There are more comments here than code. The basic idea is that we emit
the initializer, create the alloca, then update the symbol table to
point to it. Once all the variables are installed in the symbol table,
we evaluate the body of the var/in expression:

.. code-block:: ocaml

          (* Codegen the body, now that all vars are in scope. *)
          let body_val = codegen_expr body in

Finally, before returning, we restore the previous variable bindings:

.. code-block:: ocaml

          (* Pop all our variables from scope. *)
          List.iter (fun (var_name, old_value) ->
            Hashtbl.add named_values var_name old_value
          ) !old_bindings;

          (* Return the body computation. *)
          body_val

The end result of all of this is that we get properly scoped variable
definitions, and we even (trivially) allow mutation of them :).

With this, we completed what we set out to do. Our nice iterative fib
example from the intro compiles and runs just fine. The mem2reg pass
optimizes all of our stack variables into SSA registers, inserting PHI
nodes where needed, and our front-end remains simple: no "iterated
dominance frontier" computation anywhere in sight.

Full Code Listing
=================

Here is the complete code listing for our running example, enhanced with
mutable variables and var/in support. To build this example, use:

.. code-block:: bash

    # Compile
    ocamlbuild toy.byte
    # Run
    ./toy.byte

Here is the code:

\_tags:
    ::

        <{lexer,parser}.ml>: use_camlp4, pp(camlp4of)
        <*.{byte,native}>: g++, use_llvm, use_llvm_analysis
        <*.{byte,native}>: use_llvm_executionengine, use_llvm_target
        <*.{byte,native}>: use_llvm_scalar_opts, use_bindings

myocamlbuild.ml:
    .. code-block:: ocaml

        open Ocamlbuild_plugin;;

        ocaml_lib ~extern:true "llvm";;
        ocaml_lib ~extern:true "llvm_analysis";;
        ocaml_lib ~extern:true "llvm_executionengine";;
        ocaml_lib ~extern:true "llvm_target";;
        ocaml_lib ~extern:true "llvm_scalar_opts";;

        flag ["link"; "ocaml"; "g++"] (S[A"-cc"; A"g++"; A"-cclib"; A"-rdynamic"]);;
        dep ["link"; "ocaml"; "use_bindings"] ["bindings.o"];;

token.ml:
    .. code-block:: ocaml

        (*===----------------------------------------------------------------------===
         * Lexer Tokens
         *===----------------------------------------------------------------------===*)

        (* The lexer returns these 'Kwd' if it is an unknown character, otherwise one of
         * these others for known things. *)
        type token =
          (* commands *)
          | Def | Extern

          (* primary *)
          | Ident of string | Number of float

          (* unknown *)
          | Kwd of char

          (* control *)
          | If | Then | Else
          | For | In

          (* operators *)
          | Binary | Unary

          (* var definition *)
          | Var

lexer.ml:
    .. code-block:: ocaml

        (*===----------------------------------------------------------------------===
         * Lexer
         *===----------------------------------------------------------------------===*)

        let rec lex = parser
          (* Skip any whitespace. *)
          | [< ' (' ' | '\n' | '\r' | '\t'); stream >] -> lex stream

          (* identifier: [a-zA-Z][a-zA-Z0-9] *)
          | [< ' ('A' .. 'Z' | 'a' .. 'z' as c); stream >] ->
              let buffer = Buffer.create 1 in
              Buffer.add_char buffer c;
              lex_ident buffer stream

          (* number: [0-9.]+ *)
          | [< ' ('0' .. '9' as c); stream >] ->
              let buffer = Buffer.create 1 in
              Buffer.add_char buffer c;
              lex_number buffer stream

          (* Comment until end of line. *)
          | [< ' ('#'); stream >] ->
              lex_comment stream

          (* Otherwise, just return the character as its ascii value. *)
          | [< 'c; stream >] ->
              [< 'Token.Kwd c; lex stream >]

          (* end of stream. *)
          | [< >] -> [< >]

        and lex_number buffer = parser
          | [< ' ('0' .. '9' | '.' as c); stream >] ->
              Buffer.add_char buffer c;
              lex_number buffer stream
          | [< stream=lex >] ->
              [< 'Token.Number (float_of_string (Buffer.contents buffer)); stream >]

        and lex_ident buffer = parser
          | [< ' ('A' .. 'Z' | 'a' .. 'z' | '0' .. '9' as c); stream >] ->
              Buffer.add_char buffer c;
              lex_ident buffer stream
          | [< stream=lex >] ->
              match Buffer.contents buffer with
              | "def" -> [< 'Token.Def; stream >]
              | "extern" -> [< 'Token.Extern; stream >]
              | "if" -> [< 'Token.If; stream >]
              | "then" -> [< 'Token.Then; stream >]
              | "else" -> [< 'Token.Else; stream >]
              | "for" -> [< 'Token.For; stream >]
              | "in" -> [< 'Token.In; stream >]
              | "binary" -> [< 'Token.Binary; stream >]
              | "unary" -> [< 'Token.Unary; stream >]
              | "var" -> [< 'Token.Var; stream >]
              | id -> [< 'Token.Ident id; stream >]

        and lex_comment = parser
          | [< ' ('\n'); stream=lex >] -> stream
          | [< 'c; e=lex_comment >] -> e
          | [< >] -> [< >]

ast.ml:
    .. code-block:: ocaml

        (*===----------------------------------------------------------------------===
         * Abstract Syntax Tree (aka Parse Tree)
         *===----------------------------------------------------------------------===*)

        (* expr - Base type for all expression nodes. *)
        type expr =
          (* variant for numeric literals like "1.0". *)
          | Number of float

          (* variant for referencing a variable, like "a". *)
          | Variable of string

          (* variant for a unary operator. *)
          | Unary of char * expr

          (* variant for a binary operator. *)
          | Binary of char * expr * expr

          (* variant for function calls. *)
          | Call of string * expr array

          (* variant for if/then/else. *)
          | If of expr * expr * expr

          (* variant for for/in. *)
          | For of string * expr * expr * expr option * expr

          (* variant for var/in. *)
          | Var of (string * expr option) array * expr

        (* proto - This type represents the "prototype" for a function, which captures
         * its name, and its argument names (thus implicitly the number of arguments the
         * function takes). *)
        type proto =
          | Prototype of string * string array
          | BinOpPrototype of string * string array * int

        (* func - This type represents a function definition itself. *)
        type func = Function of proto * expr

parser.ml:
    .. code-block:: ocaml

        (*===---------------------------------------------------------------------===
         * Parser
         *===---------------------------------------------------------------------===*)

        (* binop_precedence - This holds the precedence for each binary operator that is
         * defined *)
        let binop_precedence:(char, int) Hashtbl.t = Hashtbl.create 10

        (* precedence - Get the precedence of the pending binary operator token. *)
        let precedence c = try Hashtbl.find binop_precedence c with Not_found -> -1

        (* primary
         *   ::= identifier
         *   ::= numberexpr
         *   ::= parenexpr
         *   ::= ifexpr
         *   ::= forexpr
         *   ::= varexpr *)
        let rec parse_primary = parser
          (* numberexpr ::= number *)
          | [< 'Token.Number n >] -> Ast.Number n

          (* parenexpr ::= '(' expression ')' *)
          | [< 'Token.Kwd '('; e=parse_expr; 'Token.Kwd ')' ?? "expected ')'" >] -> e

          (* identifierexpr
           *   ::= identifier
           *   ::= identifier '(' argumentexpr ')' *)
          | [< 'Token.Ident id; stream >] ->
              let rec parse_args accumulator = parser
                | [< e=parse_expr; stream >] ->
                    begin parser
                      | [< 'Token.Kwd ','; e=parse_args (e :: accumulator) >] -> e
                      | [< >] -> e :: accumulator
                    end stream
                | [< >] -> accumulator
              in
              let rec parse_ident id = parser
                (* Call. *)
                | [< 'Token.Kwd '(';
                     args=parse_args [];
                     'Token.Kwd ')' ?? "expected ')'">] ->
                    Ast.Call (id, Array.of_list (List.rev args))

                (* Simple variable ref. *)
                | [< >] -> Ast.Variable id
              in
              parse_ident id stream

          (* ifexpr ::= 'if' expr 'then' expr 'else' expr *)
          | [< 'Token.If; c=parse_expr;
               'Token.Then ?? "expected 'then'"; t=parse_expr;
               'Token.Else ?? "expected 'else'"; e=parse_expr >] ->
              Ast.If (c, t, e)

          (* forexpr
                ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression *)
          | [< 'Token.For;
               'Token.Ident id ?? "expected identifier after for";
               'Token.Kwd '=' ?? "expected '=' after for";
               stream >] ->
              begin parser
                | [<
                     start=parse_expr;
                     'Token.Kwd ',' ?? "expected ',' after for";
                     end_=parse_expr;
                     stream >] ->
                    let step =
                      begin parser
                      | [< 'Token.Kwd ','; step=parse_expr >] -> Some step
                      | [< >] -> None
                      end stream
                    in
                    begin parser
                    | [< 'Token.In; body=parse_expr >] ->
                        Ast.For (id, start, end_, step, body)
                    | [< >] ->
                        raise (Stream.Error "expected 'in' after for")
                    end stream
                | [< >] ->
                    raise (Stream.Error "expected '=' after for")
              end stream

          (* varexpr
           *   ::= 'var' identifier ('=' expression?
           *             (',' identifier ('=' expression)?)* 'in' expression *)
          | [< 'Token.Var;
               (* At least one variable name is required. *)
               'Token.Ident id ?? "expected identifier after var";
               init=parse_var_init;
               var_names=parse_var_names [(id, init)];
               (* At this point, we have to have 'in'. *)
               'Token.In ?? "expected 'in' keyword after 'var'";
               body=parse_expr >] ->
              Ast.Var (Array.of_list (List.rev var_names), body)

          | [< >] -> raise (Stream.Error "unknown token when expecting an expression.")

        (* unary
         *   ::= primary
         *   ::= '!' unary *)
        and parse_unary = parser
          (* If this is a unary operator, read it. *)
          | [< 'Token.Kwd op when op != '(' && op != ')'; operand=parse_expr >] ->
              Ast.Unary (op, operand)

          (* If the current token is not an operator, it must be a primary expr. *)
          | [< stream >] -> parse_primary stream

        (* binoprhs
         *   ::= ('+' primary)* *)
        and parse_bin_rhs expr_prec lhs stream =
          match Stream.peek stream with
          (* If this is a binop, find its precedence. *)
          | Some (Token.Kwd c) when Hashtbl.mem binop_precedence c ->
              let token_prec = precedence c in

              (* If this is a binop that binds at least as tightly as the current binop,
               * consume it, otherwise we are done. *)
              if token_prec < expr_prec then lhs else begin
                (* Eat the binop. *)
                Stream.junk stream;

                (* Parse the primary expression after the binary operator. *)
                let rhs = parse_unary stream in

                (* Okay, we know this is a binop. *)
                let rhs =
                  match Stream.peek stream with
                  | Some (Token.Kwd c2) ->
                      (* If BinOp binds less tightly with rhs than the operator after
                       * rhs, let the pending operator take rhs as its lhs. *)
                      let next_prec = precedence c2 in
                      if token_prec < next_prec
                      then parse_bin_rhs (token_prec + 1) rhs stream
                      else rhs
                  | _ -> rhs
                in

                (* Merge lhs/rhs. *)
                let lhs = Ast.Binary (c, lhs, rhs) in
                parse_bin_rhs expr_prec lhs stream
              end
          | _ -> lhs

        and parse_var_init = parser
          (* read in the optional initializer. *)
          | [< 'Token.Kwd '='; e=parse_expr >] -> Some e
          | [< >] -> None

        and parse_var_names accumulator = parser
          | [< 'Token.Kwd ',';
               'Token.Ident id ?? "expected identifier list after var";
               init=parse_var_init;
               e=parse_var_names ((id, init) :: accumulator) >] -> e
          | [< >] -> accumulator

        (* expression
         *   ::= primary binoprhs *)
        and parse_expr = parser
          | [< lhs=parse_unary; stream >] -> parse_bin_rhs 0 lhs stream

        (* prototype
         *   ::= id '(' id* ')'
         *   ::= binary LETTER number? (id, id)
         *   ::= unary LETTER number? (id) *)
        let parse_prototype =
          let rec parse_args accumulator = parser
            | [< 'Token.Ident id; e=parse_args (id::accumulator) >] -> e
            | [< >] -> accumulator
          in
          let parse_operator = parser
            | [< 'Token.Unary >] -> "unary", 1
            | [< 'Token.Binary >] -> "binary", 2
          in
          let parse_binary_precedence = parser
            | [< 'Token.Number n >] -> int_of_float n
            | [< >] -> 30
          in
          parser
          | [< 'Token.Ident id;
               'Token.Kwd '(' ?? "expected '(' in prototype";
               args=parse_args [];
               'Token.Kwd ')' ?? "expected ')' in prototype" >] ->
              (* success. *)
              Ast.Prototype (id, Array.of_list (List.rev args))
          | [< (prefix, kind)=parse_operator;
               'Token.Kwd op ?? "expected an operator";
               (* Read the precedence if present. *)
               binary_precedence=parse_binary_precedence;
               'Token.Kwd '(' ?? "expected '(' in prototype";
                args=parse_args [];
               'Token.Kwd ')' ?? "expected ')' in prototype" >] ->
              let name = prefix ^ (String.make 1 op) in
              let args = Array.of_list (List.rev args) in

              (* Verify right number of arguments for operator. *)
              if Array.length args != kind
              then raise (Stream.Error "invalid number of operands for operator")
              else
                if kind == 1 then
                  Ast.Prototype (name, args)
                else
                  Ast.BinOpPrototype (name, args, binary_precedence)
          | [< >] ->
              raise (Stream.Error "expected function name in prototype")

        (* definition ::= 'def' prototype expression *)
        let parse_definition = parser
          | [< 'Token.Def; p=parse_prototype; e=parse_expr >] ->
              Ast.Function (p, e)

        (* toplevelexpr ::= expression *)
        let parse_toplevel = parser
          | [< e=parse_expr >] ->
              (* Make an anonymous proto. *)
              Ast.Function (Ast.Prototype ("", [||]), e)

        (*  external ::= 'extern' prototype *)
        let parse_extern = parser
          | [< 'Token.Extern; e=parse_prototype >] -> e

codegen.ml:
    .. code-block:: ocaml

        (*===----------------------------------------------------------------------===
         * Code Generation
         *===----------------------------------------------------------------------===*)

        open Llvm

        exception Error of string

        let context = global_context ()
        let the_module = create_module context "my cool jit"
        let builder = builder context
        let named_values:(string, llvalue) Hashtbl.t = Hashtbl.create 10
        let double_type = double_type context

        (* Create an alloca instruction in the entry block of the function. This
         * is used for mutable variables etc. *)
        let create_entry_block_alloca the_function var_name =
          let builder = builder_at context (instr_begin (entry_block the_function)) in
          build_alloca double_type var_name builder

        let rec codegen_expr = function
          | Ast.Number n -> const_float double_type n
          | Ast.Variable name ->
              let v = try Hashtbl.find named_values name with
                | Not_found -> raise (Error "unknown variable name")
              in
              (* Load the value. *)
              build_load v name builder
          | Ast.Unary (op, operand) ->
              let operand = codegen_expr operand in
              let callee = "unary" ^ (String.make 1 op) in
              let callee =
                match lookup_function callee the_module with
                | Some callee -> callee
                | None -> raise (Error "unknown unary operator")
              in
              build_call callee [|operand|] "unop" builder
          | Ast.Binary (op, lhs, rhs) ->
              begin match op with
              | '=' ->
                  (* Special case '=' because we don't want to emit the LHS as an
                   * expression. *)
                  let name =
                    match lhs with
                    | Ast.Variable name -> name
                    | _ -> raise (Error "destination of '=' must be a variable")
                  in

                  (* Codegen the rhs. *)
                  let val_ = codegen_expr rhs in

                  (* Lookup the name. *)
                  let variable = try Hashtbl.find named_values name with
                  | Not_found -> raise (Error "unknown variable name")
                  in
                  ignore(build_store val_ variable builder);
                  val_
              | _ ->
                  let lhs_val = codegen_expr lhs in
                  let rhs_val = codegen_expr rhs in
                  begin
                    match op with
                    | '+' -> build_add lhs_val rhs_val "addtmp" builder
                    | '-' -> build_sub lhs_val rhs_val "subtmp" builder
                    | '*' -> build_mul lhs_val rhs_val "multmp" builder
                    | '<' ->
                        (* Convert bool 0/1 to double 0.0 or 1.0 *)
                        let i = build_fcmp Fcmp.Ult lhs_val rhs_val "cmptmp" builder in
                        build_uitofp i double_type "booltmp" builder
                    | _ ->
                        (* If it wasn't a builtin binary operator, it must be a user defined
                         * one. Emit a call to it. *)
                        let callee = "binary" ^ (String.make 1 op) in
                        let callee =
                          match lookup_function callee the_module with
                          | Some callee -> callee
                          | None -> raise (Error "binary operator not found!")
                        in
                        build_call callee [|lhs_val; rhs_val|] "binop" builder
                  end
              end
          | Ast.Call (callee, args) ->
              (* Look up the name in the module table. *)
              let callee =
                match lookup_function callee the_module with
                | Some callee -> callee
                | None -> raise (Error "unknown function referenced")
              in
              let params = params callee in

              (* If argument mismatch error. *)
              if Array.length params == Array.length args then () else
                raise (Error "incorrect # arguments passed");
              let args = Array.map codegen_expr args in
              build_call callee args "calltmp" builder
          | Ast.If (cond, then_, else_) ->
              let cond = codegen_expr cond in

              (* Convert condition to a bool by comparing equal to 0.0 *)
              let zero = const_float double_type 0.0 in
              let cond_val = build_fcmp Fcmp.One cond zero "ifcond" builder in

              (* Grab the first block so that we might later add the conditional branch
               * to it at the end of the function. *)
              let start_bb = insertion_block builder in
              let the_function = block_parent start_bb in

              let then_bb = append_block context "then" the_function in

              (* Emit 'then' value. *)
              position_at_end then_bb builder;
              let then_val = codegen_expr then_ in

              (* Codegen of 'then' can change the current block, update then_bb for the
               * phi. We create a new name because one is used for the phi node, and the
               * other is used for the conditional branch. *)
              let new_then_bb = insertion_block builder in

              (* Emit 'else' value. *)
              let else_bb = append_block context "else" the_function in
              position_at_end else_bb builder;
              let else_val = codegen_expr else_ in

              (* Codegen of 'else' can change the current block, update else_bb for the
               * phi. *)
              let new_else_bb = insertion_block builder in

              (* Emit merge block. *)
              let merge_bb = append_block context "ifcont" the_function in
              position_at_end merge_bb builder;
              let incoming = [(then_val, new_then_bb); (else_val, new_else_bb)] in
              let phi = build_phi incoming "iftmp" builder in

              (* Return to the start block to add the conditional branch. *)
              position_at_end start_bb builder;
              ignore (build_cond_br cond_val then_bb else_bb builder);

              (* Set a unconditional branch at the end of the 'then' block and the
               * 'else' block to the 'merge' block. *)
              position_at_end new_then_bb builder; ignore (build_br merge_bb builder);
              position_at_end new_else_bb builder; ignore (build_br merge_bb builder);

              (* Finally, set the builder to the end of the merge block. *)
              position_at_end merge_bb builder;

              phi
          | Ast.For (var_name, start, end_, step, body) ->
              (* Output this as:
               *   var = alloca double
               *   ...
               *   start = startexpr
               *   store start -> var
               *   goto loop
               * loop:
               *   ...
               *   bodyexpr
               *   ...
               * loopend:
               *   step = stepexpr
               *   endcond = endexpr
               *
               *   curvar = load var
               *   nextvar = curvar + step
               *   store nextvar -> var
               *   br endcond, loop, endloop
               * outloop: *)

              let the_function = block_parent (insertion_block builder) in

              (* Create an alloca for the variable in the entry block. *)
              let alloca = create_entry_block_alloca the_function var_name in

              (* Emit the start code first, without 'variable' in scope. *)
              let start_val = codegen_expr start in

              (* Store the value into the alloca. *)
              ignore(build_store start_val alloca builder);

              (* Make the new basic block for the loop header, inserting after current
               * block. *)
              let loop_bb = append_block context "loop" the_function in

              (* Insert an explicit fall through from the current block to the
               * loop_bb. *)
              ignore (build_br loop_bb builder);

              (* Start insertion in loop_bb. *)
              position_at_end loop_bb builder;

              (* Within the loop, the variable is defined equal to the PHI node. If it
               * shadows an existing variable, we have to restore it, so save it
               * now. *)
              let old_val =
                try Some (Hashtbl.find named_values var_name) with Not_found -> None
              in
              Hashtbl.add named_values var_name alloca;

              (* Emit the body of the loop.  This, like any other expr, can change the
               * current BB.  Note that we ignore the value computed by the body, but
               * don't allow an error *)
              ignore (codegen_expr body);

              (* Emit the step value. *)
              let step_val =
                match step with
                | Some step -> codegen_expr step
                (* If not specified, use 1.0. *)
                | None -> const_float double_type 1.0
              in

              (* Compute the end condition. *)
              let end_cond = codegen_expr end_ in

              (* Reload, increment, and restore the alloca. This handles the case where
               * the body of the loop mutates the variable. *)
              let cur_var = build_load alloca var_name builder in
              let next_var = build_add cur_var step_val "nextvar" builder in
              ignore(build_store next_var alloca builder);

              (* Convert condition to a bool by comparing equal to 0.0. *)
              let zero = const_float double_type 0.0 in
              let end_cond = build_fcmp Fcmp.One end_cond zero "loopcond" builder in

              (* Create the "after loop" block and insert it. *)
              let after_bb = append_block context "afterloop" the_function in

              (* Insert the conditional branch into the end of loop_end_bb. *)
              ignore (build_cond_br end_cond loop_bb after_bb builder);

              (* Any new code will be inserted in after_bb. *)
              position_at_end after_bb builder;

              (* Restore the unshadowed variable. *)
              begin match old_val with
              | Some old_val -> Hashtbl.add named_values var_name old_val
              | None -> ()
              end;

              (* for expr always returns 0.0. *)
              const_null double_type
          | Ast.Var (var_names, body) ->
              let old_bindings = ref [] in

              let the_function = block_parent (insertion_block builder) in

              (* Register all variables and emit their initializer. *)
              Array.iter (fun (var_name, init) ->
                (* Emit the initializer before adding the variable to scope, this
                 * prevents the initializer from referencing the variable itself, and
                 * permits stuff like this:
                 *   var a = 1 in
                 *     var a = a in ...   # refers to outer 'a'. *)
                let init_val =
                  match init with
                  | Some init -> codegen_expr init
                  (* If not specified, use 0.0. *)
                  | None -> const_float double_type 0.0
                in

                let alloca = create_entry_block_alloca the_function var_name in
                ignore(build_store init_val alloca builder);

                (* Remember the old variable binding so that we can restore the binding
                 * when we unrecurse. *)
                begin
                  try
                    let old_value = Hashtbl.find named_values var_name in
                    old_bindings := (var_name, old_value) :: !old_bindings;
                  with Not_found -> ()
                end;

                (* Remember this binding. *)
                Hashtbl.add named_values var_name alloca;
              ) var_names;

              (* Codegen the body, now that all vars are in scope. *)
              let body_val = codegen_expr body in

              (* Pop all our variables from scope. *)
              List.iter (fun (var_name, old_value) ->
                Hashtbl.add named_values var_name old_value
              ) !old_bindings;

              (* Return the body computation. *)
              body_val

        let codegen_proto = function
          | Ast.Prototype (name, args) | Ast.BinOpPrototype (name, args, _) ->
              (* Make the function type: double(double,double) etc. *)
              let doubles = Array.make (Array.length args) double_type in
              let ft = function_type double_type doubles in
              let f =
                match lookup_function name the_module with
                | None -> declare_function name ft the_module

                (* If 'f' conflicted, there was already something named 'name'. If it
                 * has a body, don't allow redefinition or reextern. *)
                | Some f ->
                    (* If 'f' already has a body, reject this. *)
                    if block_begin f <> At_end f then
                      raise (Error "redefinition of function");

                    (* If 'f' took a different number of arguments, reject. *)
                    if element_type (type_of f) <> ft then
                      raise (Error "redefinition of function with different # args");
                    f
              in

              (* Set names for all arguments. *)
              Array.iteri (fun i a ->
                let n = args.(i) in
                set_value_name n a;
                Hashtbl.add named_values n a;
              ) (params f);
              f

        (* Create an alloca for each argument and register the argument in the symbol
         * table so that references to it will succeed. *)
        let create_argument_allocas the_function proto =
          let args = match proto with
            | Ast.Prototype (_, args) | Ast.BinOpPrototype (_, args, _) -> args
          in
          Array.iteri (fun i ai ->
            let var_name = args.(i) in
            (* Create an alloca for this variable. *)
            let alloca = create_entry_block_alloca the_function var_name in

            (* Store the initial value into the alloca. *)
            ignore(build_store ai alloca builder);

            (* Add arguments to variable symbol table. *)
            Hashtbl.add named_values var_name alloca;
          ) (params the_function)

        let codegen_func the_fpm = function
          | Ast.Function (proto, body) ->
              Hashtbl.clear named_values;
              let the_function = codegen_proto proto in

              (* If this is an operator, install it. *)
              begin match proto with
              | Ast.BinOpPrototype (name, args, prec) ->
                  let op = name.[String.length name - 1] in
                  Hashtbl.add Parser.binop_precedence op prec;
              | _ -> ()
              end;

              (* Create a new basic block to start insertion into. *)
              let bb = append_block context "entry" the_function in
              position_at_end bb builder;

              try
                (* Add all arguments to the symbol table and create their allocas. *)
                create_argument_allocas the_function proto;

                let ret_val = codegen_expr body in

                (* Finish off the function. *)
                let _ = build_ret ret_val builder in

                (* Validate the generated code, checking for consistency. *)
                Llvm_analysis.assert_valid_function the_function;

                (* Optimize the function. *)
                let _ = PassManager.run_function the_function the_fpm in

                the_function
              with e ->
                delete_function the_function;
                raise e

toplevel.ml:
    .. code-block:: ocaml

        (*===----------------------------------------------------------------------===
         * Top-Level parsing and JIT Driver
         *===----------------------------------------------------------------------===*)

        open Llvm
        open Llvm_executionengine

        (* top ::= definition | external | expression | ';' *)
        let rec main_loop the_fpm the_execution_engine stream =
          match Stream.peek stream with
          | None -> ()

          (* ignore top-level semicolons. *)
          | Some (Token.Kwd ';') ->
              Stream.junk stream;
              main_loop the_fpm the_execution_engine stream

          | Some token ->
              begin
                try match token with
                | Token.Def ->
                    let e = Parser.parse_definition stream in
                    print_endline "parsed a function definition.";
                    dump_value (Codegen.codegen_func the_fpm e);
                | Token.Extern ->
                    let e = Parser.parse_extern stream in
                    print_endline "parsed an extern.";
                    dump_value (Codegen.codegen_proto e);
                | _ ->
                    (* Evaluate a top-level expression into an anonymous function. *)
                    let e = Parser.parse_toplevel stream in
                    print_endline "parsed a top-level expr";
                    let the_function = Codegen.codegen_func the_fpm e in
                    dump_value the_function;

                    (* JIT the function, returning a function pointer. *)
                    let result = ExecutionEngine.run_function the_function [||]
                      the_execution_engine in

                    print_string "Evaluated to ";
                    print_float (GenericValue.as_float Codegen.double_type result);
                    print_newline ();
                with Stream.Error s | Codegen.Error s ->
                  (* Skip token for error recovery. *)
                  Stream.junk stream;
                  print_endline s;
              end;
              print_string "ready> "; flush stdout;
              main_loop the_fpm the_execution_engine stream

toy.ml:
    .. code-block:: ocaml

        (*===----------------------------------------------------------------------===
         * Main driver code.
         *===----------------------------------------------------------------------===*)

        open Llvm
        open Llvm_executionengine
        open Llvm_target
        open Llvm_scalar_opts

        let main () =
          ignore (initialize_native_target ());

          (* Install standard binary operators.
           * 1 is the lowest precedence. *)
          Hashtbl.add Parser.binop_precedence '=' 2;
          Hashtbl.add Parser.binop_precedence '<' 10;
          Hashtbl.add Parser.binop_precedence '+' 20;
          Hashtbl.add Parser.binop_precedence '-' 20;
          Hashtbl.add Parser.binop_precedence '*' 40;    (* highest. *)

          (* Prime the first token. *)
          print_string "ready> "; flush stdout;
          let stream = Lexer.lex (Stream.of_channel stdin) in

          (* Create the JIT. *)
          let the_execution_engine = ExecutionEngine.create Codegen.the_module in
          let the_fpm = PassManager.create_function Codegen.the_module in

          (* Set up the optimizer pipeline.  Start with registering info about how the
           * target lays out data structures. *)
          DataLayout.add (ExecutionEngine.target_data the_execution_engine) the_fpm;

          (* Promote allocas to registers. *)
          add_memory_to_register_promotion the_fpm;

          (* Do simple "peephole" optimizations and bit-twiddling optzn. *)
          add_instruction_combination the_fpm;

          (* reassociate expressions. *)
          add_reassociation the_fpm;

          (* Eliminate Common SubExpressions. *)
          add_gvn the_fpm;

          (* Simplify the control flow graph (deleting unreachable blocks, etc). *)
          add_cfg_simplification the_fpm;

          ignore (PassManager.initialize the_fpm);

          (* Run the main "interpreter loop" now. *)
          Toplevel.main_loop the_fpm the_execution_engine stream;

          (* Print out all the generated code. *)
          dump_module Codegen.the_module
        ;;

        main ()

bindings.c
    .. code-block:: c

        #include <stdio.h>

        /* putchard - putchar that takes a double and returns 0. */
        extern double putchard(double X) {
          putchar((char)X);
          return 0;
        }

        /* printd - printf that takes a double prints it as "%f\n", returning 0. */
        extern double printd(double X) {
          printf("%f\n", X);
          return 0;
        }

`Next: Conclusion and other useful LLVM tidbits <OCamlLangImpl8.html>`_

