<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="author" content="Chris Lattner">
<meta name="author" content="Erick Tryzelaar">
- <link rel="stylesheet" href="../llvm.css" type="text/css">
+ <link rel="stylesheet" href="../_static/llvm.css" type="text/css">
</head>
<body>
-<div class="doc_title">Kaleidoscope: Extending the Language: Control Flow</div>
+<h1>Kaleidoscope: Extending the Language: Control Flow</h1>
<ul>
<li><a href="index.html">Up to Tutorial Index</a></li>
</div>
<!-- *********************************************************************** -->
-<div class="doc_section"><a name="intro">Chapter 5 Introduction</a></div>
+<h2><a name="intro">Chapter 5 Introduction</a></h2>
<!-- *********************************************************************** -->
-<div class="doc_text">
+<div>
<p>Welcome to Chapter 5 of the "<a href="index.html">Implementing a language
with LLVM</a>" tutorial. Parts 1-4 described the implementation of the simple
</div>
<!-- *********************************************************************** -->
-<div class="doc_section"><a name="ifthen">If/Then/Else</a></div>
+<h2><a name="ifthen">If/Then/Else</a></h2>
<!-- *********************************************************************** -->
-<div class="doc_text">
+<div>
<p>
Extending Kaleidoscope to support if/then/else is quite straightforward. It
<p>Now that we know what we "want", lets break this down into its constituent
pieces.</p>
-</div>
-
<!-- ======================================================================= -->
-<div class="doc_subsubsection"><a name="iflexer">Lexer Extensions for
-If/Then/Else</a></div>
+<h4><a name="iflexer">Lexer Extensions for If/Then/Else</a></h4>
<!-- ======================================================================= -->
-<div class="doc_text">
+<div>
<p>The lexer extensions are straightforward. First we add new variants
for the relevant tokens:</p>
</div>
<!-- ======================================================================= -->
-<div class="doc_subsubsection"><a name="ifast">AST Extensions for
- If/Then/Else</a></div>
+<h4><a name="ifast">AST Extensions for If/Then/Else</a></h4>
<!-- ======================================================================= -->
-<div class="doc_text">
+<div>
<p>To represent the new expression we add a new AST variant for it:</p>
</div>
<!-- ======================================================================= -->
-<div class="doc_subsubsection"><a name="ifparser">Parser Extensions for
-If/Then/Else</a></div>
+<h4><a name="ifparser">Parser Extensions for If/Then/Else</a></h4>
<!-- ======================================================================= -->
-<div class="doc_text">
+<div>
<p>Now that we have the relevant tokens coming from the lexer and we have the
AST node to build, our parsing logic is relatively straightforward. First we
</div>
<!-- ======================================================================= -->
-<div class="doc_subsubsection"><a name="ifir">LLVM IR for If/Then/Else</a></div>
+<h4><a name="ifir">LLVM IR for If/Then/Else</a></h4>
<!-- ======================================================================= -->
-<div class="doc_text">
+<div>
<p>Now that we have it parsing and building the AST, the final piece is adding
LLVM code generation support. This is the most interesting part of the
href="../ProgrammersManual.html#ViewGraph">a window will pop up</a> and you'll
see this graph:</p>
-<center><img src="LangImpl5-cfg.png" alt="Example CFG" width="423"
-height="315"></center>
+<div style="text-align: center"><img src="LangImpl5-cfg.png" alt="Example CFG" width="423"
+height="315"></div>
<p>Another way to get this is to call "<tt>Llvm_analysis.view_function_cfg
f</tt>" or "<tt>Llvm_analysis.view_function_cfg_only f</tt>" (where <tt>f</tt>
</div>
<!-- ======================================================================= -->
-<div class="doc_subsubsection"><a name="ifcodegen">Code Generation for
-If/Then/Else</a></div>
+<h4><a name="ifcodegen">Code Generation for If/Then/Else</a></h4>
<!-- ======================================================================= -->
-<div class="doc_text">
+<div>
<p>In order to generate code for this, we implement the <tt>Codegen</tt> method
for <tt>IfExprAST</tt>:</p>
let start_bb = insertion_block builder in
let the_function = block_parent start_bb in
- let then_bb = append_block "then" the_function in
+ let then_bb = append_block context "then" the_function in
position_at_end then_bb builder;
</pre>
</div>
<div class="doc_code">
<pre>
(* Emit 'else' value. *)
- let else_bb = append_block "else" the_function in
+ let else_bb = append_block context "else" the_function in
position_at_end else_bb builder;
let else_val = codegen_expr else_ in
<div class="doc_code">
<pre>
(* Emit merge block. *)
- let merge_bb = append_block "ifcont" the_function in
+ 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
</div>
+</div>
+
<!-- *********************************************************************** -->
-<div class="doc_section"><a name="for">'for' Loop Expression</a></div>
+<h2><a name="for">'for' Loop Expression</a></h2>
<!-- *********************************************************************** -->
-<div class="doc_text">
+<div>
<p>Now that we know how to add basic control flow constructs to the language,
we have the tools to add more powerful things. Lets add something more
<p>As before, lets talk about the changes that we need to Kaleidoscope to
support this.</p>
-</div>
-
<!-- ======================================================================= -->
-<div class="doc_subsubsection"><a name="forlexer">Lexer Extensions for
-the 'for' Loop</a></div>
+<h4><a name="forlexer">Lexer Extensions for the 'for' Loop</a></h4>
<!-- ======================================================================= -->
-<div class="doc_text">
+<div>
<p>The lexer extensions are the same sort of thing as for if/then/else:</p>
</div>
<!-- ======================================================================= -->
-<div class="doc_subsubsection"><a name="forast">AST Extensions for
-the 'for' Loop</a></div>
+<h4><a name="forast">AST Extensions for the 'for' Loop</a></h4>
<!-- ======================================================================= -->
-<div class="doc_text">
+<div>
<p>The AST variant is just as simple. It basically boils down to capturing
the variable name and the constituent expressions in the node.</p>
</div>
<!-- ======================================================================= -->
-<div class="doc_subsubsection"><a name="forparser">Parser Extensions for
-the 'for' Loop</a></div>
+<h4><a name="forparser">Parser Extensions for the 'for' Loop</a></h4>
<!-- ======================================================================= -->
-<div class="doc_text">
+<div>
<p>The parser code is also fairly standard. The only interesting thing here is
handling of the optional step value. The parser code handles it by checking to
</div>
<!-- ======================================================================= -->
-<div class="doc_subsubsection"><a name="forir">LLVM IR for
-the 'for' Loop</a></div>
+<h4><a name="forir">LLVM IR for the 'for' Loop</a></h4>
<!-- ======================================================================= -->
-<div class="doc_text">
+<div>
<p>Now we get to the good part: the LLVM IR we want to generate for this thing.
With the simple example above, we get this LLVM IR (note that this dump is
loop: ; preds = %loop, %entry
%i = phi double [ 1.000000e+00, %entry ], [ %nextvar, %loop ]
; body
- %calltmp = call double @putchard( double 4.200000e+01 )
+ %calltmp = call double @putchard(double 4.200000e+01)
; increment
- %nextvar = add double %i, 1.000000e+00
+ %nextvar = fadd double %i, 1.000000e+00
; termination test
%cmptmp = fcmp ult double %i, %n
</div>
<!-- ======================================================================= -->
-<div class="doc_subsubsection"><a name="forcodegen">Code Generation for
-the 'for' Loop</a></div>
+<h4><a name="forcodegen">Code Generation for the 'for' Loop</a></h4>
<!-- ======================================================================= -->
-<div class="doc_text">
+<div>
<p>The first part of Codegen is very simple: we just output the start expression
for the loop value:</p>
* block. *)
let preheader_bb = insertion_block builder in
let the_function = block_parent preheader_bb in
- let loop_bb = append_block "loop" the_function in
+ let loop_bb = append_block context "loop" the_function in
(* Insert an explicit fall through from the current block to the
* loop_bb. *)
<pre>
(* Create the "after loop" block and insert it. *)
let loop_end_bb = insertion_block builder in
- let after_bb = append_block "afterloop" the_function in
+ 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);
</div>
+</div>
+
<!-- *********************************************************************** -->
-<div class="doc_section"><a name="code">Full Code Listing</a></div>
+<h2><a name="code">Full Code Listing</a></h2>
<!-- *********************************************************************** -->
-<div class="doc_text">
+<div>
<p>
Here is the complete code listing for our running example, enhanced with the
exception Error of string
-let the_module = create_module "my cool jit"
-let builder = builder ()
+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
let rec codegen_expr = function
| Ast.Number n -> const_float double_type n
let start_bb = insertion_block builder in
let the_function = block_parent start_bb in
- let then_bb = append_block "then" the_function in
+ let then_bb = append_block context "then" the_function in
(* Emit 'then' value. *)
position_at_end then_bb builder;
let new_then_bb = insertion_block builder in
(* Emit 'else' value. *)
- let else_bb = append_block "else" the_function in
+ let else_bb = append_block context "else" the_function in
position_at_end else_bb builder;
let else_val = codegen_expr else_ in
let new_else_bb = insertion_block builder in
(* Emit merge block. *)
- let merge_bb = append_block "ifcont" the_function in
+ 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
* block. *)
let preheader_bb = insertion_block builder in
let the_function = block_parent preheader_bb in
- let loop_bb = append_block "loop" the_function in
+ let loop_bb = append_block context "loop" the_function in
(* Insert an explicit fall through from the current block to the
* loop_bb. *)
(* Create the "after loop" block and insert it. *)
let loop_end_bb = insertion_block builder in
- let after_bb = append_block "afterloop" the_function in
+ 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);
let the_function = codegen_proto proto in
(* Create a new basic block to start insertion into. *)
- let bb = append_block "entry" the_function in
+ let bb = append_block context "entry" the_function in
position_at_end bb builder;
try
the_execution_engine in
print_string "Evaluated to ";
- print_float (GenericValue.as_float double_type result);
+ print_float (GenericValue.as_float Codegen.double_type result);
print_newline ();
with Stream.Error s | Codegen.Error s ->
(* Skip token for error recovery. *)
open Llvm_scalar_opts
let main () =
+ ignore (initialize_native_target ());
+
(* Install standard binary operators.
* 1 is the lowest precedence. *)
Hashtbl.add Parser.binop_precedence '<' 10;
let stream = Lexer.lex (Stream.of_channel stdin) in
(* Create the JIT. *)
- let the_module_provider = ModuleProvider.create Codegen.the_module in
- let the_execution_engine = ExecutionEngine.create the_module_provider in
- let the_fpm = PassManager.create_function the_module_provider in
+ 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. *)
- TargetData.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
+ DataLayout.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
(* Do simple "peephole" optimizations and bit-twiddling optzn. *)
- add_instruction_combining the_fpm;
+ add_instruction_combination the_fpm;
(* reassociate expressions. *)
add_reassociation 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;
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
- <a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
+ <a href="http://llvm.org/">The LLVM Compiler Infrastructure</a><br>
+ Last modified: $Date$
</address>
</body>
</html>