<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
                      "http://www.w3.org/TR/html4/strict.dtd">

<html>
<head>
  <title>Kaleidoscope: Extending the Language: Mutable Variables / SSA
         construction</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta name="author" content="Chris Lattner">
  <link rel="stylesheet" href="../llvm.css" type="text/css">
</head>

<body>

<div class="doc_title">Kaleidoscope: Extending the Language: Mutable Variables</div>

<ul>
<li><a href="index.html">Up to Tutorial Index</a></li>
<li>Chapter 7
  <ol>
    <li><a href="#intro">Chapter 7 Introduction</a></li>
    <li><a href="#why">Why is this a hard problem?</a></li>
    <li><a href="#memory">Memory in LLVM</a></li>
    <li><a href="#kalvars">Mutable Variables in Kaleidoscope</a></li>
    <li><a href="#adjustments">Adjusting Existing Variables for
     Mutation</a></li>
    <li><a href="#assignment">New Assignment Operator</a></li>
    <li><a href="#localvars">User-defined Local Variables</a></li>
    <li><a href="#code">Full Code Listing</a></li>
  </ol>
</li>
<li><a href="LangImpl8.html">Chapter 8</a>: Conclusion and other useful LLVM
 tidbits</li>
</ul>

<div class="doc_author">
  <p>Written by <a href="mailto:sabre@nondot.org">Chris Lattner</a></p>
</div>

<!-- *********************************************************************** -->
<div class="doc_section"><a name="intro">Chapter 7 Introduction</a></div>
<!-- *********************************************************************** -->

<div class="doc_text">

<p>Welcome to Chapter 7 of the "<a href="index.html">Implementing a language
with LLVM</a>" tutorial.  In chapters 1 through 6, we've built a very
respectable, albeit simple, <a 
href="http://en.wikipedia.org/wiki/Functional_programming">functional
programming language</a>.  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.</p>

<p>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 <a 
href="http://en.wikipedia.org/wiki/Static_single_assignment_form">SSA form</a>.
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.</p>

<p>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.</p>

</div>

<!-- *********************************************************************** -->
<div class="doc_section"><a name="why">Why is this a hard problem?</a></div>
<!-- *********************************************************************** -->

<div class="doc_text">

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

<div class="doc_code">
<pre>
int G, H;
int test(_Bool Condition) {
  int X;
  if (Condition)
    X = G;
  else
    X = H;
  return X;
}
</pre>
</div>

<p>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:</p>

<div class="doc_code">
<pre>
@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
}
</pre>
</div>

<p>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 <a 
href="http://en.wikipedia.org/wiki/Static_single_assignment_form">online 
references</a>.</p>

<p>The question for this article is "who places the phi nodes when lowering 
assignments to mutable variables?".  The issue here is that LLVM 
<em>requires</em> 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.</p>

</div>

<!-- *********************************************************************** -->
<div class="doc_section"><a name="memory">Memory in LLVM</a></div>
<!-- *********************************************************************** -->

<div class="doc_text">

<p>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 <a 
href="../WritingAnLLVMPass.html">Analysis Passes</a> which are computed on
demand.</p>

<p>
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.
</p>

<p>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 <em>space</em>
for an i32 in the global data area, but its <em>name</em> 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 
<a href="../LangRef.html#i_alloca">LLVM alloca instruction</a>:</p>

<div class="doc_code">
<pre>
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
	...
</pre>
</div>

<p>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:</p>

<div class="doc_code">
<pre>
@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
}
</pre>
</div>

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

<ol>
<li>Each mutable variable becomes a stack allocation.</li>
<li>Each read of the variable becomes a load from the stack.</li>
<li>Each update of the variable becomes a store to the stack.</li>
<li>Taking the address of a variable just uses the stack address directly.</li>
</ol>

<p>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:</p>

<div class="doc_code">
<pre>
$ <b>llvm-as &lt; example.ll | opt -mem2reg | llvm-dis</b>
@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
}
</pre>
</div>

<p>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:</p>

<ol>
<li>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.</li>

<li>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.</li>

<li>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.</li>

<li>mem2reg only works on allocas of <a 
href="../LangRef.html#t_classifications">first class</a> 
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 "scalarrepl" pass is
more powerful and can promote structs, "unions", and arrays in many cases.</li>

</ol>

<p>
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:</p>

<ul>
<li>Proven and well tested: llvm-gcc and clang both use 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.</li>

<li>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.
</li>

<li>Needed for debug info generation: <a href="../SourceLevelDebugging.html">
Debug information in LLVM</a> 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.</li>
</ul>

<p>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!
</p>

</div>

<!-- *********************************************************************** -->
<div class="doc_section"><a name="kalvars">Mutable Variables in 
Kaleidoscope</a></div>
<!-- *********************************************************************** -->

<div class="doc_text">

<p>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:</p>

<ol>
<li>The ability to mutate variables with the '=' operator.</li>
<li>The ability to define new variables.</li>
</ol>

<p>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:</p>

<div class="doc_code">
<pre>
# 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 &lt; 3) then
    1
  else
    fib(x-1)+fib(x-2);

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

# Call it. 
fibi(10);
</pre>
</div>

<p>
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.
</p>

</div>

<!-- *********************************************************************** -->
<div class="doc_section"><a name="adjustments">Adjusting Existing Variables for
Mutation</a></div>
<!-- *********************************************************************** -->

<div class="doc_text">

<p>
The symbol table in Kaleidoscope is managed at code generation time by the 
'<tt>NamedValues</tt>' 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 <tt>NamedValues</tt> holds
the <em>memory location</em> 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.</p>

<p>
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.
</p>

<p>To start our transformation of Kaleidoscope, we'll change the NamedValues
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:</p>

<div class="doc_code">
<pre>
static std::map&lt;std::string, AllocaInst*&gt; NamedValues;
</pre>
</div>

<p>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:</p>

<div class="doc_code">
<pre>
/// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of
/// the function.  This is used for mutable variables etc.
static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
                                          const std::string &amp;VarName) {
  IRBuilder&lt;&gt; TmpB(&amp;TheFunction-&gt;getEntryBlock(),
                 TheFunction-&gt;getEntryBlock().begin());
  return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), 0,
                           VarName.c_str());
}
</pre>
</div>

<p>This funny looking code creates an IRBuilder object that is pointing at
the first instruction (.begin()) 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.</p>

<p>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:</p>

<div class="doc_code">
<pre>
Value *VariableExprAST::Codegen() {
  // Look this variable up in the function.
  Value *V = NamedValues[Name];
  if (V == 0) return ErrorV("Unknown variable name");

  <b>// Load the value.
  return Builder.CreateLoad(V, Name.c_str());</b>
}
</pre>
</div>

<p>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 
<tt>ForExprAST::Codegen</tt> (see the <a href="#code">full code listing</a> for
the unabridged code):</p>

<div class="doc_code">
<pre>
  Function *TheFunction = Builder.GetInsertBlock()->getParent();

  <b>// Create an alloca for the variable in the entry block.
  AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);</b>
  
    // Emit the start code first, without 'variable' in scope.
  Value *StartVal = Start-&gt;Codegen();
  if (StartVal == 0) return 0;
  
  <b>// Store the value into the alloca.
  Builder.CreateStore(StartVal, Alloca);</b>
  ...

  // Compute the end condition.
  Value *EndCond = End-&gt;Codegen();
  if (EndCond == 0) return EndCond;
  
  <b>// Reload, increment, and restore the alloca.  This handles the case where
  // the body of the loop mutates the variable.
  Value *CurVar = Builder.CreateLoad(Alloca);
  Value *NextVar = Builder.CreateAdd(CurVar, StepVal, "nextvar");
  Builder.CreateStore(NextVar, Alloca);</b>
  ...
</pre>
</div>

<p>This code is virtually identical to the code <a 
href="LangImpl5.html#forcodegen">before we allowed mutable variables</a>.  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.</p>

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

<div class="doc_code">
<pre>
/// CreateArgumentAllocas - Create an alloca for each argument and register the
/// argument in the symbol table so that references to it will succeed.
void PrototypeAST::CreateArgumentAllocas(Function *F) {
  Function::arg_iterator AI = F-&gt;arg_begin();
  for (unsigned Idx = 0, e = Args.size(); Idx != e; ++Idx, ++AI) {
    // Create an alloca for this variable.
    AllocaInst *Alloca = CreateEntryBlockAlloca(F, Args[Idx]);

    // Store the initial value into the alloca.
    Builder.CreateStore(AI, Alloca);

    // Add arguments to variable symbol table.
    NamedValues[Args[Idx]] = Alloca;
  }
}
</pre>
</div>

<p>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 <tt>FunctionAST::Codegen</tt> right after
it sets up the entry block for the function.</p>

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

<div class="doc_code">
<pre>
    // Set up the optimizer pipeline.  Start with registering info about how the
    // target lays out data structures.
    OurFPM.add(new TargetData(*TheExecutionEngine-&gt;getTargetData()));
    <b>// Promote allocas to registers.
    OurFPM.add(createPromoteMemoryToRegisterPass());</b>
    // Do simple "peephole" optimizations and bit-twiddling optzns.
    OurFPM.add(createInstructionCombiningPass());
    // Reassociate expressions.
    OurFPM.add(createReassociatePass());
</pre>
</div>

<p>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:</p>

<div class="doc_code">
<pre>
define double @fib(double %x) {
entry:
	<b>%x1 = alloca double
	store double %x, double* %x1
	%x2 = load double* %x1</b>
	%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
	<b>%x3 = load double* %x1</b>
	%subtmp = fsub double %x3, 1.000000e+00
	%calltmp = call double @fib( double %subtmp )
	<b>%x4 = load double* %x1</b>
	%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
}
</pre>
</div>

<p>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.</p>

<p>Here is the code after the mem2reg pass runs:</p>

<div class="doc_code">
<pre>
define double @fib(double %x) {
entry:
	%cmptmp = fcmp ult double <b>%x</b>, 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 <b>%x</b>, 1.000000e+00
	%calltmp = call double @fib( double %subtmp )
	%subtmp5 = fsub double <b>%x</b>, 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
}
</pre>
</div>

<p>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 :).</p>

<p>After the rest of the optimizers run, we get:</p>

<div class="doc_code">
<pre>
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
}
</pre>
</div>

<p>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.</p>

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

</div>

<!-- *********************************************************************** -->
<div class="doc_section"><a name="assignment">New Assignment Operator</a></div>
<!-- *********************************************************************** -->

<div class="doc_text">

<p>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:</p>

<div class="doc_code">
<pre>
 int main() {
   // Install standard binary operators.
   // 1 is lowest precedence.
   <b>BinopPrecedence['='] = 2;</b>
   BinopPrecedence['&lt;'] = 10;
   BinopPrecedence['+'] = 20;
   BinopPrecedence['-'] = 20;
</pre>
</div>

<p>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:</p> 

<div class="doc_code">
<pre>
Value *BinaryExprAST::Codegen() {
  // Special case '=' because we don't want to emit the LHS as an expression.
  if (Op == '=') {
    // Assignment requires the LHS to be an identifier.
    VariableExprAST *LHSE = dynamic_cast&lt;VariableExprAST*&gt;(LHS);
    if (!LHSE)
      return ErrorV("destination of '=' must be a variable");
</pre>
</div>

<p>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.
</p>

<div class="doc_code">
<pre>
    // Codegen the RHS.
    Value *Val = RHS-&gt;Codegen();
    if (Val == 0) return 0;

    // Look up the name.
    Value *Variable = NamedValues[LHSE-&gt;getName()];
    if (Variable == 0) return ErrorV("Unknown variable name");

    Builder.CreateStore(Val, Variable);
    return Val;
  }
  ...  
</pre>
</div>

<p>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)".</p>

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

<div class="doc_code">
<pre>
# 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);
</pre>
</div>

<p>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! 
</p>

</div>

<!-- *********************************************************************** -->
<div class="doc_section"><a name="localvars">User-defined Local 
Variables</a></div>
<!-- *********************************************************************** -->

<div class="doc_text">

<p>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:</p>

<div class="doc_code">
<pre>
enum Token {
  ...
  <b>// var definition
  tok_var = -13</b>
...
}
...
static int gettok() {
...
    if (IdentifierStr == "in") return tok_in;
    if (IdentifierStr == "binary") return tok_binary;
    if (IdentifierStr == "unary") return tok_unary;
    <b>if (IdentifierStr == "var") return tok_var;</b>
    return tok_identifier;
...
</pre>
</div>

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

<div class="doc_code">
<pre>
/// VarExprAST - Expression class for var/in
class VarExprAST : public ExprAST {
  std::vector&lt;std::pair&lt;std::string, ExprAST*&gt; &gt; VarNames;
  ExprAST *Body;
public:
  VarExprAST(const std::vector&lt;std::pair&lt;std::string, ExprAST*&gt; &gt; &amp;varnames,
             ExprAST *body)
  : VarNames(varnames), Body(body) {}
  
  virtual Value *Codegen();
};
</pre>
</div>

<p>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.</p>

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

<div class="doc_code">
<pre>
/// primary
///   ::= identifierexpr
///   ::= numberexpr
///   ::= parenexpr
///   ::= ifexpr
///   ::= forexpr
<b>///   ::= varexpr</b>
static ExprAST *ParsePrimary() {
  switch (CurTok) {
  default: return Error("unknown token when expecting an expression");
  case tok_identifier: return ParseIdentifierExpr();
  case tok_number:     return ParseNumberExpr();
  case '(':            return ParseParenExpr();
  case tok_if:         return ParseIfExpr();
  case tok_for:        return ParseForExpr();
  <b>case tok_var:        return ParseVarExpr();</b>
  }
}
</pre>
</div>

<p>Next we define ParseVarExpr:</p>

<div class="doc_code">
<pre>
/// varexpr ::= 'var' identifier ('=' expression)? 
//                    (',' identifier ('=' expression)?)* 'in' expression
static ExprAST *ParseVarExpr() {
  getNextToken();  // eat the var.

  std::vector&lt;std::pair&lt;std::string, ExprAST*&gt; &gt; VarNames;

  // At least one variable name is required.
  if (CurTok != tok_identifier)
    return Error("expected identifier after var");
</pre>
</div>

<p>The first part of this code parses the list of identifier/expr pairs into the
local <tt>VarNames</tt> vector.  

<div class="doc_code">
<pre>
  while (1) {
    std::string Name = IdentifierStr;
    getNextToken();  // eat identifier.

    // Read the optional initializer.
    ExprAST *Init = 0;
    if (CurTok == '=') {
      getNextToken(); // eat the '='.
      
      Init = ParseExpression();
      if (Init == 0) return 0;
    }
    
    VarNames.push_back(std::make_pair(Name, Init));
    
    // End of var list, exit loop.
    if (CurTok != ',') break;
    getNextToken(); // eat the ','.
    
    if (CurTok != tok_identifier)
      return Error("expected identifier list after var");
  }
</pre>
</div>

<p>Once all the variables are parsed, we then parse the body and create the
AST node:</p>

<div class="doc_code">
<pre>
  // At this point, we have to have 'in'.
  if (CurTok != tok_in)
    return Error("expected 'in' keyword after 'var'");
  getNextToken();  // eat 'in'.
  
  ExprAST *Body = ParseExpression();
  if (Body == 0) return 0;
  
  return new VarExprAST(VarNames, Body);
}
</pre>
</div>

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

<div class="doc_code">
<pre>
Value *VarExprAST::Codegen() {
  std::vector&lt;AllocaInst *&gt; OldBindings;
  
  Function *TheFunction = Builder.GetInsertBlock()-&gt;getParent();

  // Register all variables and emit their initializer.
  for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
    const std::string &amp;VarName = VarNames[i].first;
    ExprAST *Init = VarNames[i].second;
</pre>
</div>

<p>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.</p>

<div class="doc_code">
<pre>
    // 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'.
    Value *InitVal;
    if (Init) {
      InitVal = Init-&gt;Codegen();
      if (InitVal == 0) return 0;
    } else { // If not specified, use 0.0.
      InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0));
    }
    
    AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
    Builder.CreateStore(InitVal, Alloca);

    // Remember the old variable binding so that we can restore the binding when
    // we unrecurse.
    OldBindings.push_back(NamedValues[VarName]);
    
    // Remember this binding.
    NamedValues[VarName] = Alloca;
  }
</pre>
</div>

<p>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:</p>

<div class="doc_code">
<pre>
  // Codegen the body, now that all vars are in scope.
  Value *BodyVal = Body-&gt;Codegen();
  if (BodyVal == 0) return 0;
</pre>
</div>

<p>Finally, before returning, we restore the previous variable bindings:</p>

<div class="doc_code">
<pre>
  // Pop all our variables from scope.
  for (unsigned i = 0, e = VarNames.size(); i != e; ++i)
    NamedValues[VarNames[i].first] = OldBindings[i];

  // Return the body computation.
  return BodyVal;
}
</pre>
</div>

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

<p>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.</p>

</div>

<!-- *********************************************************************** -->
<div class="doc_section"><a name="code">Full Code Listing</a></div>
<!-- *********************************************************************** -->

<div class="doc_text">

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

<div class="doc_code">
<pre>
   # Compile
   g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
   # Run
   ./toy
</pre>
</div>

<p>Here is the code:</p>

<div class="doc_code">
<pre>
#include "llvm/DerivedTypes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/IRBuilder.h"
#include &lt;cstdio&gt;
#include &lt;string&gt;
#include &lt;map&gt;
#include &lt;vector&gt;
using namespace llvm;

//===----------------------------------------------------------------------===//
// Lexer
//===----------------------------------------------------------------------===//

// The lexer returns tokens [0-255] if it is an unknown character, otherwise one
// of these for known things.
enum Token {
  tok_eof = -1,

  // commands
  tok_def = -2, tok_extern = -3,

  // primary
  tok_identifier = -4, tok_number = -5,
  
  // control
  tok_if = -6, tok_then = -7, tok_else = -8,
  tok_for = -9, tok_in = -10,
  
  // operators
  tok_binary = -11, tok_unary = -12,
  
  // var definition
  tok_var = -13
};

static std::string IdentifierStr;  // Filled in if tok_identifier
static double NumVal;              // Filled in if tok_number

/// gettok - Return the next token from standard input.
static int gettok() {
  static int LastChar = ' ';

  // Skip any whitespace.
  while (isspace(LastChar))
    LastChar = getchar();

  if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
    IdentifierStr = LastChar;
    while (isalnum((LastChar = getchar())))
      IdentifierStr += LastChar;

    if (IdentifierStr == "def") return tok_def;
    if (IdentifierStr == "extern") return tok_extern;
    if (IdentifierStr == "if") return tok_if;
    if (IdentifierStr == "then") return tok_then;
    if (IdentifierStr == "else") return tok_else;
    if (IdentifierStr == "for") return tok_for;
    if (IdentifierStr == "in") return tok_in;
    if (IdentifierStr == "binary") return tok_binary;
    if (IdentifierStr == "unary") return tok_unary;
    if (IdentifierStr == "var") return tok_var;
    return tok_identifier;
  }

  if (isdigit(LastChar) || LastChar == '.') {   // Number: [0-9.]+
    std::string NumStr;
    do {
      NumStr += LastChar;
      LastChar = getchar();
    } while (isdigit(LastChar) || LastChar == '.');

    NumVal = strtod(NumStr.c_str(), 0);
    return tok_number;
  }

  if (LastChar == '#') {
    // Comment until end of line.
    do LastChar = getchar();
    while (LastChar != EOF &amp;&amp; LastChar != '\n' &amp;&amp; LastChar != '\r');
    
    if (LastChar != EOF)
      return gettok();
  }
  
  // Check for end of file.  Don't eat the EOF.
  if (LastChar == EOF)
    return tok_eof;

  // Otherwise, just return the character as its ascii value.
  int ThisChar = LastChar;
  LastChar = getchar();
  return ThisChar;
}

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

/// ExprAST - Base class for all expression nodes.
class ExprAST {
public:
  virtual ~ExprAST() {}
  virtual Value *Codegen() = 0;
};

/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
  double Val;
public:
  NumberExprAST(double val) : Val(val) {}
  virtual Value *Codegen();
};

/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
  std::string Name;
public:
  VariableExprAST(const std::string &amp;name) : Name(name) {}
  const std::string &amp;getName() const { return Name; }
  virtual Value *Codegen();
};

/// UnaryExprAST - Expression class for a unary operator.
class UnaryExprAST : public ExprAST {
  char Opcode;
  ExprAST *Operand;
public:
  UnaryExprAST(char opcode, ExprAST *operand) 
    : Opcode(opcode), Operand(operand) {}
  virtual Value *Codegen();
};

/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
  char Op;
  ExprAST *LHS, *RHS;
public:
  BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs) 
    : Op(op), LHS(lhs), RHS(rhs) {}
  virtual Value *Codegen();
};

/// CallExprAST - Expression class for function calls.
class CallExprAST : public ExprAST {
  std::string Callee;
  std::vector&lt;ExprAST*&gt; Args;
public:
  CallExprAST(const std::string &amp;callee, std::vector&lt;ExprAST*&gt; &amp;args)
    : Callee(callee), Args(args) {}
  virtual Value *Codegen();
};

/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
  ExprAST *Cond, *Then, *Else;
public:
  IfExprAST(ExprAST *cond, ExprAST *then, ExprAST *_else)
  : Cond(cond), Then(then), Else(_else) {}
  virtual Value *Codegen();
};

/// ForExprAST - Expression class for for/in.
class ForExprAST : public ExprAST {
  std::string VarName;
  ExprAST *Start, *End, *Step, *Body;
public:
  ForExprAST(const std::string &amp;varname, ExprAST *start, ExprAST *end,
             ExprAST *step, ExprAST *body)
    : VarName(varname), Start(start), End(end), Step(step), Body(body) {}
  virtual Value *Codegen();
};

/// VarExprAST - Expression class for var/in
class VarExprAST : public ExprAST {
  std::vector&lt;std::pair&lt;std::string, ExprAST*&gt; &gt; VarNames;
  ExprAST *Body;
public:
  VarExprAST(const std::vector&lt;std::pair&lt;std::string, ExprAST*&gt; &gt; &amp;varnames,
             ExprAST *body)
  : VarNames(varnames), Body(body) {}
  
  virtual Value *Codegen();
};

/// PrototypeAST - This class represents the "prototype" for a function,
/// which captures its name, and its argument names (thus implicitly the number
/// of arguments the function takes), as well as if it is an operator.
class PrototypeAST {
  std::string Name;
  std::vector&lt;std::string&gt; Args;
  bool isOperator;
  unsigned Precedence;  // Precedence if a binary op.
public:
  PrototypeAST(const std::string &amp;name, const std::vector&lt;std::string&gt; &amp;args,
               bool isoperator = false, unsigned prec = 0)
  : Name(name), Args(args), isOperator(isoperator), Precedence(prec) {}
  
  bool isUnaryOp() const { return isOperator &amp;&amp; Args.size() == 1; }
  bool isBinaryOp() const { return isOperator &amp;&amp; Args.size() == 2; }
  
  char getOperatorName() const {
    assert(isUnaryOp() || isBinaryOp());
    return Name[Name.size()-1];
  }
  
  unsigned getBinaryPrecedence() const { return Precedence; }
  
  Function *Codegen();
  
  void CreateArgumentAllocas(Function *F);
};

/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
  PrototypeAST *Proto;
  ExprAST *Body;
public:
  FunctionAST(PrototypeAST *proto, ExprAST *body)
    : Proto(proto), Body(body) {}
  
  Function *Codegen();
};

//===----------------------------------------------------------------------===//
// Parser
//===----------------------------------------------------------------------===//

/// CurTok/getNextToken - Provide a simple token buffer.  CurTok is the current
/// token the parser is looking at.  getNextToken reads another token from the
/// lexer and updates CurTok with its results.
static int CurTok;
static int getNextToken() {
  return CurTok = gettok();
}

/// BinopPrecedence - This holds the precedence for each binary operator that is
/// defined.
static std::map&lt;char, int&gt; BinopPrecedence;

/// GetTokPrecedence - Get the precedence of the pending binary operator token.
static int GetTokPrecedence() {
  if (!isascii(CurTok))
    return -1;
  
  // Make sure it's a declared binop.
  int TokPrec = BinopPrecedence[CurTok];
  if (TokPrec &lt;= 0) return -1;
  return TokPrec;
}

/// Error* - These are little helper functions for error handling.
ExprAST *Error(const char *Str) { fprintf(stderr, "Error: %s\n", Str);return 0;}
PrototypeAST *ErrorP(const char *Str) { Error(Str); return 0; }
FunctionAST *ErrorF(const char *Str) { Error(Str); return 0; }

static ExprAST *ParseExpression();

/// identifierexpr
///   ::= identifier
///   ::= identifier '(' expression* ')'
static ExprAST *ParseIdentifierExpr() {
  std::string IdName = IdentifierStr;
  
  getNextToken();  // eat identifier.
  
  if (CurTok != '(') // Simple variable ref.
    return new VariableExprAST(IdName);
  
  // Call.
  getNextToken();  // eat (
  std::vector&lt;ExprAST*&gt; Args;
  if (CurTok != ')') {
    while (1) {
      ExprAST *Arg = ParseExpression();
      if (!Arg) return 0;
      Args.push_back(Arg);

      if (CurTok == ')') break;

      if (CurTok != ',')
        return Error("Expected ')' or ',' in argument list");
      getNextToken();
    }
  }

  // Eat the ')'.
  getNextToken();
  
  return new CallExprAST(IdName, Args);
}

/// numberexpr ::= number
static ExprAST *ParseNumberExpr() {
  ExprAST *Result = new NumberExprAST(NumVal);
  getNextToken(); // consume the number
  return Result;
}

/// parenexpr ::= '(' expression ')'
static ExprAST *ParseParenExpr() {
  getNextToken();  // eat (.
  ExprAST *V = ParseExpression();
  if (!V) return 0;
  
  if (CurTok != ')')
    return Error("expected ')'");
  getNextToken();  // eat ).
  return V;
}

/// ifexpr ::= 'if' expression 'then' expression 'else' expression
static ExprAST *ParseIfExpr() {
  getNextToken();  // eat the if.
  
  // condition.
  ExprAST *Cond = ParseExpression();
  if (!Cond) return 0;
  
  if (CurTok != tok_then)
    return Error("expected then");
  getNextToken();  // eat the then
  
  ExprAST *Then = ParseExpression();
  if (Then == 0) return 0;
  
  if (CurTok != tok_else)
    return Error("expected else");
  
  getNextToken();
  
  ExprAST *Else = ParseExpression();
  if (!Else) return 0;
  
  return new IfExprAST(Cond, Then, Else);
}

/// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression
static ExprAST *ParseForExpr() {
  getNextToken();  // eat the for.

  if (CurTok != tok_identifier)
    return Error("expected identifier after for");
  
  std::string IdName = IdentifierStr;
  getNextToken();  // eat identifier.
  
  if (CurTok != '=')
    return Error("expected '=' after for");
  getNextToken();  // eat '='.
  
  
  ExprAST *Start = ParseExpression();
  if (Start == 0) return 0;
  if (CurTok != ',')
    return Error("expected ',' after for start value");
  getNextToken();
  
  ExprAST *End = ParseExpression();
  if (End == 0) return 0;
  
  // The step value is optional.
  ExprAST *Step = 0;
  if (CurTok == ',') {
    getNextToken();
    Step = ParseExpression();
    if (Step == 0) return 0;
  }
  
  if (CurTok != tok_in)
    return Error("expected 'in' after for");
  getNextToken();  // eat 'in'.
  
  ExprAST *Body = ParseExpression();
  if (Body == 0) return 0;

  return new ForExprAST(IdName, Start, End, Step, Body);
}

/// varexpr ::= 'var' identifier ('=' expression)? 
//                    (',' identifier ('=' expression)?)* 'in' expression
static ExprAST *ParseVarExpr() {
  getNextToken();  // eat the var.

  std::vector&lt;std::pair&lt;std::string, ExprAST*&gt; &gt; VarNames;

  // At least one variable name is required.
  if (CurTok != tok_identifier)
    return Error("expected identifier after var");
  
  while (1) {
    std::string Name = IdentifierStr;
    getNextToken();  // eat identifier.

    // Read the optional initializer.
    ExprAST *Init = 0;
    if (CurTok == '=') {
      getNextToken(); // eat the '='.
      
      Init = ParseExpression();
      if (Init == 0) return 0;
    }
    
    VarNames.push_back(std::make_pair(Name, Init));
    
    // End of var list, exit loop.
    if (CurTok != ',') break;
    getNextToken(); // eat the ','.
    
    if (CurTok != tok_identifier)
      return Error("expected identifier list after var");
  }
  
  // At this point, we have to have 'in'.
  if (CurTok != tok_in)
    return Error("expected 'in' keyword after 'var'");
  getNextToken();  // eat 'in'.
  
  ExprAST *Body = ParseExpression();
  if (Body == 0) return 0;
  
  return new VarExprAST(VarNames, Body);
}

/// primary
///   ::= identifierexpr
///   ::= numberexpr
///   ::= parenexpr
///   ::= ifexpr
///   ::= forexpr
///   ::= varexpr
static ExprAST *ParsePrimary() {
  switch (CurTok) {
  default: return Error("unknown token when expecting an expression");
  case tok_identifier: return ParseIdentifierExpr();
  case tok_number:     return ParseNumberExpr();
  case '(':            return ParseParenExpr();
  case tok_if:         return ParseIfExpr();
  case tok_for:        return ParseForExpr();
  case tok_var:        return ParseVarExpr();
  }
}

/// unary
///   ::= primary
///   ::= '!' unary
static ExprAST *ParseUnary() {
  // If the current token is not an operator, it must be a primary expr.
  if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
    return ParsePrimary();
  
  // If this is a unary operator, read it.
  int Opc = CurTok;
  getNextToken();
  if (ExprAST *Operand = ParseUnary())
    return new UnaryExprAST(Opc, Operand);
  return 0;
}

/// binoprhs
///   ::= ('+' unary)*
static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
  // If this is a binop, find its precedence.
  while (1) {
    int TokPrec = GetTokPrecedence();
    
    // If this is a binop that binds at least as tightly as the current binop,
    // consume it, otherwise we are done.
    if (TokPrec &lt; ExprPrec)
      return LHS;
    
    // Okay, we know this is a binop.
    int BinOp = CurTok;
    getNextToken();  // eat binop
    
    // Parse the unary expression after the binary operator.
    ExprAST *RHS = ParseUnary();
    if (!RHS) return 0;
    
    // If BinOp binds less tightly with RHS than the operator after RHS, let
    // the pending operator take RHS as its LHS.
    int NextPrec = GetTokPrecedence();
    if (TokPrec &lt; NextPrec) {
      RHS = ParseBinOpRHS(TokPrec+1, RHS);
      if (RHS == 0) return 0;
    }
    
    // Merge LHS/RHS.
    LHS = new BinaryExprAST(BinOp, LHS, RHS);
  }
}

/// expression
///   ::= unary binoprhs
///
static ExprAST *ParseExpression() {
  ExprAST *LHS = ParseUnary();
  if (!LHS) return 0;
  
  return ParseBinOpRHS(0, LHS);
}

/// prototype
///   ::= id '(' id* ')'
///   ::= binary LETTER number? (id, id)
///   ::= unary LETTER (id)
static PrototypeAST *ParsePrototype() {
  std::string FnName;
  
  unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
  unsigned BinaryPrecedence = 30;
  
  switch (CurTok) {
  default:
    return ErrorP("Expected function name in prototype");
  case tok_identifier:
    FnName = IdentifierStr;
    Kind = 0;
    getNextToken();
    break;
  case tok_unary:
    getNextToken();
    if (!isascii(CurTok))
      return ErrorP("Expected unary operator");
    FnName = "unary";
    FnName += (char)CurTok;
    Kind = 1;
    getNextToken();
    break;
  case tok_binary:
    getNextToken();
    if (!isascii(CurTok))
      return ErrorP("Expected binary operator");
    FnName = "binary";
    FnName += (char)CurTok;
    Kind = 2;
    getNextToken();
    
    // Read the precedence if present.
    if (CurTok == tok_number) {
      if (NumVal &lt; 1 || NumVal &gt; 100)
        return ErrorP("Invalid precedecnce: must be 1..100");
      BinaryPrecedence = (unsigned)NumVal;
      getNextToken();
    }
    break;
  }
  
  if (CurTok != '(')
    return ErrorP("Expected '(' in prototype");
  
  std::vector&lt;std::string&gt; ArgNames;
  while (getNextToken() == tok_identifier)
    ArgNames.push_back(IdentifierStr);
  if (CurTok != ')')
    return ErrorP("Expected ')' in prototype");
  
  // success.
  getNextToken();  // eat ')'.
  
  // Verify right number of names for operator.
  if (Kind &amp;&amp; ArgNames.size() != Kind)
    return ErrorP("Invalid number of operands for operator");
  
  return new PrototypeAST(FnName, ArgNames, Kind != 0, BinaryPrecedence);
}

/// definition ::= 'def' prototype expression
static FunctionAST *ParseDefinition() {
  getNextToken();  // eat def.
  PrototypeAST *Proto = ParsePrototype();
  if (Proto == 0) return 0;

  if (ExprAST *E = ParseExpression())
    return new FunctionAST(Proto, E);
  return 0;
}

/// toplevelexpr ::= expression
static FunctionAST *ParseTopLevelExpr() {
  if (ExprAST *E = ParseExpression()) {
    // Make an anonymous proto.
    PrototypeAST *Proto = new PrototypeAST("", std::vector&lt;std::string&gt;());
    return new FunctionAST(Proto, E);
  }
  return 0;
}

/// external ::= 'extern' prototype
static PrototypeAST *ParseExtern() {
  getNextToken();  // eat extern.
  return ParsePrototype();
}

//===----------------------------------------------------------------------===//
// Code Generation
//===----------------------------------------------------------------------===//

static Module *TheModule;
static IRBuilder&lt;&gt; Builder(getGlobalContext());
static std::map&lt;std::string, AllocaInst*&gt; NamedValues;
static FunctionPassManager *TheFPM;

Value *ErrorV(const char *Str) { Error(Str); return 0; }

/// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of
/// the function.  This is used for mutable variables etc.
static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
                                          const std::string &amp;VarName) {
  IRBuilder&lt;&gt; TmpB(&amp;TheFunction-&gt;getEntryBlock(),
                 TheFunction-&gt;getEntryBlock().begin());
  return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), 0,
                           VarName.c_str());
}

Value *NumberExprAST::Codegen() {
  return ConstantFP::get(getGlobalContext(), APFloat(Val));
}

Value *VariableExprAST::Codegen() {
  // Look this variable up in the function.
  Value *V = NamedValues[Name];
  if (V == 0) return ErrorV("Unknown variable name");

  // Load the value.
  return Builder.CreateLoad(V, Name.c_str());
}

Value *UnaryExprAST::Codegen() {
  Value *OperandV = Operand-&gt;Codegen();
  if (OperandV == 0) return 0;
  
  Function *F = TheModule-&gt;getFunction(std::string("unary")+Opcode);
  if (F == 0)
    return ErrorV("Unknown unary operator");
  
  return Builder.CreateCall(F, OperandV, "unop");
}

Value *BinaryExprAST::Codegen() {
  // Special case '=' because we don't want to emit the LHS as an expression.
  if (Op == '=') {
    // Assignment requires the LHS to be an identifier.
    VariableExprAST *LHSE = dynamic_cast&lt;VariableExprAST*&gt;(LHS);
    if (!LHSE)
      return ErrorV("destination of '=' must be a variable");
    // Codegen the RHS.
    Value *Val = RHS-&gt;Codegen();
    if (Val == 0) return 0;

    // Look up the name.
    Value *Variable = NamedValues[LHSE-&gt;getName()];
    if (Variable == 0) return ErrorV("Unknown variable name");

    Builder.CreateStore(Val, Variable);
    return Val;
  }
  
  Value *L = LHS-&gt;Codegen();
  Value *R = RHS-&gt;Codegen();
  if (L == 0 || R == 0) return 0;
  
  switch (Op) {
  case '+': return Builder.CreateAdd(L, R, "addtmp");
  case '-': return Builder.CreateSub(L, R, "subtmp");
  case '*': return Builder.CreateMul(L, R, "multmp");
  case '&lt;':
    L = Builder.CreateFCmpULT(L, R, "cmptmp");
    // Convert bool 0/1 to double 0.0 or 1.0
    return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()),
                                "booltmp");
  default: break;
  }
  
  // If it wasn't a builtin binary operator, it must be a user defined one. Emit
  // a call to it.
  Function *F = TheModule-&gt;getFunction(std::string("binary")+Op);
  assert(F &amp;&amp; "binary operator not found!");
  
  Value *Ops[] = { L, R };
  return Builder.CreateCall(F, Ops, Ops+2, "binop");
}

Value *CallExprAST::Codegen() {
  // Look up the name in the global module table.
  Function *CalleeF = TheModule-&gt;getFunction(Callee);
  if (CalleeF == 0)
    return ErrorV("Unknown function referenced");
  
  // If argument mismatch error.
  if (CalleeF-&gt;arg_size() != Args.size())
    return ErrorV("Incorrect # arguments passed");

  std::vector&lt;Value*&gt; ArgsV;
  for (unsigned i = 0, e = Args.size(); i != e; ++i) {
    ArgsV.push_back(Args[i]-&gt;Codegen());
    if (ArgsV.back() == 0) return 0;
  }
  
  return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp");
}

Value *IfExprAST::Codegen() {
  Value *CondV = Cond-&gt;Codegen();
  if (CondV == 0) return 0;
  
  // Convert condition to a bool by comparing equal to 0.0.
  CondV = Builder.CreateFCmpONE(CondV, 
                              ConstantFP::get(getGlobalContext(), APFloat(0.0)),
                                "ifcond");
  
  Function *TheFunction = Builder.GetInsertBlock()-&gt;getParent();
  
  // Create blocks for the then and else cases.  Insert the 'then' block at the
  // end of the function.
  BasicBlock *ThenBB = BasicBlock::Create(getGlobalContext(), "then", TheFunction);
  BasicBlock *ElseBB = BasicBlock::Create(getGlobalContext(), "else");
  BasicBlock *MergeBB = BasicBlock::Create(getGlobalContext(), "ifcont");
  
  Builder.CreateCondBr(CondV, ThenBB, ElseBB);
  
  // Emit then value.
  Builder.SetInsertPoint(ThenBB);
  
  Value *ThenV = Then-&gt;Codegen();
  if (ThenV == 0) return 0;
  
  Builder.CreateBr(MergeBB);
  // Codegen of 'Then' can change the current block, update ThenBB for the PHI.
  ThenBB = Builder.GetInsertBlock();
  
  // Emit else block.
  TheFunction-&gt;getBasicBlockList().push_back(ElseBB);
  Builder.SetInsertPoint(ElseBB);
  
  Value *ElseV = Else-&gt;Codegen();
  if (ElseV == 0) return 0;
  
  Builder.CreateBr(MergeBB);
  // Codegen of 'Else' can change the current block, update ElseBB for the PHI.
  ElseBB = Builder.GetInsertBlock();
  
  // Emit merge block.
  TheFunction-&gt;getBasicBlockList().push_back(MergeBB);
  Builder.SetInsertPoint(MergeBB);
  PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()),
                                  "iftmp");
  
  PN-&gt;addIncoming(ThenV, ThenBB);
  PN-&gt;addIncoming(ElseV, ElseBB);
  return PN;
}

Value *ForExprAST::Codegen() {
  // Output this as:
  //   var = alloca double
  //   ...
  //   start = startexpr
  //   store start -&gt; var
  //   goto loop
  // loop: 
  //   ...
  //   bodyexpr
  //   ...
  // loopend:
  //   step = stepexpr
  //   endcond = endexpr
  //
  //   curvar = load var
  //   nextvar = curvar + step
  //   store nextvar -&gt; var
  //   br endcond, loop, endloop
  // outloop:
  
  Function *TheFunction = Builder.GetInsertBlock()-&gt;getParent();

  // Create an alloca for the variable in the entry block.
  AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
  
  // Emit the start code first, without 'variable' in scope.
  Value *StartVal = Start-&gt;Codegen();
  if (StartVal == 0) return 0;
  
  // Store the value into the alloca.
  Builder.CreateStore(StartVal, Alloca);
  
  // Make the new basic block for the loop header, inserting after current
  // block.
  BasicBlock *LoopBB = BasicBlock::Create(getGlobalContext(), "loop", TheFunction);
  
  // Insert an explicit fall through from the current block to the LoopBB.
  Builder.CreateBr(LoopBB);

  // Start insertion in LoopBB.
  Builder.SetInsertPoint(LoopBB);
  
  // 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.
  AllocaInst *OldVal = NamedValues[VarName];
  NamedValues[VarName] = 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.
  if (Body-&gt;Codegen() == 0)
    return 0;
  
  // Emit the step value.
  Value *StepVal;
  if (Step) {
    StepVal = Step-&gt;Codegen();
    if (StepVal == 0) return 0;
  } else {
    // If not specified, use 1.0.
    StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
  }
  
  // Compute the end condition.
  Value *EndCond = End-&gt;Codegen();
  if (EndCond == 0) return EndCond;
  
  // Reload, increment, and restore the alloca.  This handles the case where
  // the body of the loop mutates the variable.
  Value *CurVar = Builder.CreateLoad(Alloca, VarName.c_str());
  Value *NextVar = Builder.CreateAdd(CurVar, StepVal, "nextvar");
  Builder.CreateStore(NextVar, Alloca);
  
  // Convert condition to a bool by comparing equal to 0.0.
  EndCond = Builder.CreateFCmpONE(EndCond, 
                              ConstantFP::get(getGlobalContext(), APFloat(0.0)),
                                  "loopcond");
  
  // Create the "after loop" block and insert it.
  BasicBlock *AfterBB = BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction);
  
  // Insert the conditional branch into the end of LoopEndBB.
  Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
  
  // Any new code will be inserted in AfterBB.
  Builder.SetInsertPoint(AfterBB);
  
  // Restore the unshadowed variable.
  if (OldVal)
    NamedValues[VarName] = OldVal;
  else
    NamedValues.erase(VarName);

  
  // for expr always returns 0.0.
  return Constant::getNullValue(Type::getDoubleTy(getGlobalContext()));
}

Value *VarExprAST::Codegen() {
  std::vector&lt;AllocaInst *&gt; OldBindings;
  
  Function *TheFunction = Builder.GetInsertBlock()-&gt;getParent();

  // Register all variables and emit their initializer.
  for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
    const std::string &amp;VarName = VarNames[i].first;
    ExprAST *Init = VarNames[i].second;
    
    // 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'.
    Value *InitVal;
    if (Init) {
      InitVal = Init-&gt;Codegen();
      if (InitVal == 0) return 0;
    } else { // If not specified, use 0.0.
      InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0));
    }
    
    AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
    Builder.CreateStore(InitVal, Alloca);

    // Remember the old variable binding so that we can restore the binding when
    // we unrecurse.
    OldBindings.push_back(NamedValues[VarName]);
    
    // Remember this binding.
    NamedValues[VarName] = Alloca;
  }
  
  // Codegen the body, now that all vars are in scope.
  Value *BodyVal = Body-&gt;Codegen();
  if (BodyVal == 0) return 0;
  
  // Pop all our variables from scope.
  for (unsigned i = 0, e = VarNames.size(); i != e; ++i)
    NamedValues[VarNames[i].first] = OldBindings[i];

  // Return the body computation.
  return BodyVal;
}

Function *PrototypeAST::Codegen() {
  // Make the function type:  double(double,double) etc.
  std::vector&lt;const Type*&gt; Doubles(Args.size(),
                                   Type::getDoubleTy(getGlobalContext()));
  FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
                                       Doubles, false);
  
  Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule);
  
  // If F conflicted, there was already something named 'Name'.  If it has a
  // body, don't allow redefinition or reextern.
  if (F-&gt;getName() != Name) {
    // Delete the one we just made and get the existing one.
    F-&gt;eraseFromParent();
    F = TheModule-&gt;getFunction(Name);
    
    // If F already has a body, reject this.
    if (!F-&gt;empty()) {
      ErrorF("redefinition of function");
      return 0;
    }
    
    // If F took a different number of args, reject.
    if (F-&gt;arg_size() != Args.size()) {
      ErrorF("redefinition of function with different # args");
      return 0;
    }
  }
  
  // Set names for all arguments.
  unsigned Idx = 0;
  for (Function::arg_iterator AI = F-&gt;arg_begin(); Idx != Args.size();
       ++AI, ++Idx)
    AI-&gt;setName(Args[Idx]);
    
  return F;
}

/// CreateArgumentAllocas - Create an alloca for each argument and register the
/// argument in the symbol table so that references to it will succeed.
void PrototypeAST::CreateArgumentAllocas(Function *F) {
  Function::arg_iterator AI = F-&gt;arg_begin();
  for (unsigned Idx = 0, e = Args.size(); Idx != e; ++Idx, ++AI) {
    // Create an alloca for this variable.
    AllocaInst *Alloca = CreateEntryBlockAlloca(F, Args[Idx]);

    // Store the initial value into the alloca.
    Builder.CreateStore(AI, Alloca);

    // Add arguments to variable symbol table.
    NamedValues[Args[Idx]] = Alloca;
  }
}

Function *FunctionAST::Codegen() {
  NamedValues.clear();
  
  Function *TheFunction = Proto-&gt;Codegen();
  if (TheFunction == 0)
    return 0;
  
  // If this is an operator, install it.
  if (Proto-&gt;isBinaryOp())
    BinopPrecedence[Proto-&gt;getOperatorName()] = Proto-&gt;getBinaryPrecedence();
  
  // Create a new basic block to start insertion into.
  BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
  Builder.SetInsertPoint(BB);
  
  // Add all arguments to the symbol table and create their allocas.
  Proto-&gt;CreateArgumentAllocas(TheFunction);

  if (Value *RetVal = Body-&gt;Codegen()) {
    // Finish off the function.
    Builder.CreateRet(RetVal);

    // Validate the generated code, checking for consistency.
    verifyFunction(*TheFunction);

    // Optimize the function.
    TheFPM-&gt;run(*TheFunction);
    
    return TheFunction;
  }
  
  // Error reading body, remove function.
  TheFunction-&gt;eraseFromParent();

  if (Proto-&gt;isBinaryOp())
    BinopPrecedence.erase(Proto-&gt;getOperatorName());
  return 0;
}

//===----------------------------------------------------------------------===//
// Top-Level parsing and JIT Driver
//===----------------------------------------------------------------------===//

static ExecutionEngine *TheExecutionEngine;

static void HandleDefinition() {
  if (FunctionAST *F = ParseDefinition()) {
    if (Function *LF = F-&gt;Codegen()) {
      fprintf(stderr, "Read function definition:");
      LF-&gt;dump();
    }
  } else {
    // Skip token for error recovery.
    getNextToken();
  }
}

static void HandleExtern() {
  if (PrototypeAST *P = ParseExtern()) {
    if (Function *F = P-&gt;Codegen()) {
      fprintf(stderr, "Read extern: ");
      F-&gt;dump();
    }
  } else {
    // Skip token for error recovery.
    getNextToken();
  }
}

static void HandleTopLevelExpression() {
  // Evaluate a top-level expression into an anonymous function.
  if (FunctionAST *F = ParseTopLevelExpr()) {
    if (Function *LF = F-&gt;Codegen()) {
      // JIT the function, returning a function pointer.
      void *FPtr = TheExecutionEngine-&gt;getPointerToFunction(LF);
      
      // Cast it to the right type (takes no arguments, returns a double) so we
      // can call it as a native function.
      double (*FP)() = (double (*)())(intptr_t)FPtr;
      fprintf(stderr, "Evaluated to %f\n", FP());
    }
  } else {
    // Skip token for error recovery.
    getNextToken();
  }
}

/// top ::= definition | external | expression | ';'
static void MainLoop() {
  while (1) {
    fprintf(stderr, "ready&gt; ");
    switch (CurTok) {
    case tok_eof:    return;
    case ';':        getNextToken(); break;  // ignore top-level semicolons.
    case tok_def:    HandleDefinition(); break;
    case tok_extern: HandleExtern(); break;
    default:         HandleTopLevelExpression(); break;
    }
  }
}

//===----------------------------------------------------------------------===//
// "Library" functions that can be "extern'd" from user code.
//===----------------------------------------------------------------------===//

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

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

//===----------------------------------------------------------------------===//
// Main driver code.
//===----------------------------------------------------------------------===//

int main() {
  InitializeNativeTarget();
  LLVMContext &amp;Context = getGlobalContext();

  // Install standard binary operators.
  // 1 is lowest precedence.
  BinopPrecedence['='] = 2;
  BinopPrecedence['&lt;'] = 10;
  BinopPrecedence['+'] = 20;
  BinopPrecedence['-'] = 20;
  BinopPrecedence['*'] = 40;  // highest.

  // Prime the first token.
  fprintf(stderr, "ready&gt; ");
  getNextToken();

  // Make the module, which holds all the code.
  TheModule = new Module("my cool jit", Context);

  // Create the JIT.  This takes ownership of the module.
  std::string ErrStr;
  TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&amp;ErrStr).create();
  if (!TheExecutionEngine) {
    fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
    exit(1);
  }

  FunctionPassManager OurFPM(TheModule);

  // Set up the optimizer pipeline.  Start with registering info about how the
  // target lays out data structures.
  OurFPM.add(new TargetData(*TheExecutionEngine-&gt;getTargetData()));
  // Promote allocas to registers.
  OurFPM.add(createPromoteMemoryToRegisterPass());
  // Do simple "peephole" optimizations and bit-twiddling optzns.
  OurFPM.add(createInstructionCombiningPass());
  // Reassociate expressions.
  OurFPM.add(createReassociatePass());
  // Eliminate Common SubExpressions.
  OurFPM.add(createGVNPass());
  // Simplify the control flow graph (deleting unreachable blocks, etc).
  OurFPM.add(createCFGSimplificationPass());

  OurFPM.doInitialization();

  // Set the global so the code gen can use this.
  TheFPM = &amp;OurFPM;

  // Run the main "interpreter loop" now.
  MainLoop();

  TheFPM = 0;

  // Print out all of the generated code.
  TheModule-&gt;dump();

  return 0;
}
</pre>
</div>

<a href="LangImpl8.html">Next: Conclusion and other useful LLVM tidbits</a>
</div>

<!-- *********************************************************************** -->
<hr>
<address>
  <a href="http://jigsaw.w3.org/css-validator/check/referer"><img
  src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"></a>
  <a href="http://validator.w3.org/check/referer"><img
  src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"></a>

  <a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
  <a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
  Last modified: $Date$
</address>
</body>
</html>
