<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: Mutable Variables</div>
+<h1>Kaleidoscope: Extending the Language: Mutable Variables</h1>
<ul>
<li><a href="index.html">Up to Tutorial Index</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
+<li><a href="OCamlLangImpl8.html">Chapter 8</a>: Conclusion and other useful LLVM
tidbits</li>
</ul>
</div>
<!-- *********************************************************************** -->
-<div class="doc_section"><a name="intro">Chapter 7 Introduction</a></div>
+<h2><a name="intro">Chapter 7 Introduction</a></h2>
<!-- *********************************************************************** -->
-<div class="doc_text">
+<div>
<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
</div>
<!-- *********************************************************************** -->
-<div class="doc_section"><a name="why">Why is this a hard problem?</a></div>
+<h2><a name="why">Why is this a hard problem?</a></h2>
<!-- *********************************************************************** -->
-<div class="doc_text">
+<div>
<p>
To understand why mutable variables cause complexities in SSA construction,
</div>
<!-- *********************************************************************** -->
-<div class="doc_section"><a name="memory">Memory in LLVM</a></div>
+<h2><a name="memory">Memory in LLVM</a></h2>
<!-- *********************************************************************** -->
-<div class="doc_text">
+<div>
<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.
</div>
<!-- *********************************************************************** -->
-<div class="doc_section"><a name="kalvars">Mutable Variables in
-Kaleidoscope</a></div>
+<h2><a name="kalvars">Mutable Variables in Kaleidoscope</a></h2>
<!-- *********************************************************************** -->
-<div class="doc_text">
+<div>
<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
</div>
<!-- *********************************************************************** -->
-<div class="doc_section"><a name="adjustments">Adjusting Existing Variables for
-Mutation</a></div>
+<h2><a name="adjustments">Adjusting Existing Variables for Mutation</a></h2>
<!-- *********************************************************************** -->
-<div class="doc_text">
+<div>
<p>
The symbol table in Kaleidoscope is managed at code generation time by the
<pre>
let main () =
...
- let the_fpm = PassManager.create_function the_module_provider 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;
<b>(* Promote allocas to registers. *)
add_memory_to_register_promotion the_fpm;</b>
else: ; preds = %entry
<b>%x3 = load double* %x1</b>
- %subtmp = sub double %x3, 1.000000e+00
- %calltmp = call double @fib( double %subtmp )
+ %subtmp = fsub double %x3, 1.000000e+00
+ %calltmp = call double @fib(double %subtmp)
<b>%x4 = load double* %x1</b>
- %subtmp5 = sub double %x4, 2.000000e+00
- %calltmp6 = call double @fib( double %subtmp5 )
- %addtmp = add double %calltmp, %calltmp6
+ %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
br label %ifcont
else:
- %subtmp = sub double <b>%x</b>, 1.000000e+00
- %calltmp = call double @fib( double %subtmp )
- %subtmp5 = sub double <b>%x</b>, 2.000000e+00
- %calltmp6 = call double @fib( double %subtmp5 )
- %addtmp = add double %calltmp, %calltmp6
+ %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
br i1 %ifcond, label %else, label %ifcont
else:
- %subtmp = sub double %x, 1.000000e+00
- %calltmp = call double @fib( double %subtmp )
- %subtmp5 = sub double %x, 2.000000e+00
- %calltmp6 = call double @fib( double %subtmp5 )
- %addtmp = add double %calltmp, %calltmp6
+ %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:
</div>
<!-- *********************************************************************** -->
-<div class="doc_section"><a name="assignment">New Assignment Operator</a></div>
+<h2><a name="assignment">New Assignment Operator</a></h2>
<!-- *********************************************************************** -->
-<div class="doc_text">
+<div>
<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
</div>
<!-- *********************************************************************** -->
-<div class="doc_section"><a name="localvars">User-defined Local
-Variables</a></div>
+<h2><a name="localvars">User-defined Local Variables</a></h2>
<!-- *********************************************************************** -->
-<div class="doc_text">
+<div>
<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.
</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 mutable
ocaml_lib ~extern:true "llvm_target";;
ocaml_lib ~extern:true "llvm_scalar_opts";;
-flag ["link"; "ocaml"; "g++"] (S[A"-cc"; A"g++"]);;
+flag ["link"; "ocaml"; "g++"] (S[A"-cc"; A"g++"; A"-cclib"; A"-rdynamic"]);;
dep ["link"; "ocaml"; "use_bindings"] ["bindings.o"];;
</pre>
</dd>
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 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
(* Make the new basic block for the loop header, inserting after current
* block. *)
- 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. *)
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 "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);
end;
(* 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. *)
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;
(* Promote allocas to registers. *)
add_memory_to_register_promotion 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;
</dd>
</dl>
-<a href="LangImpl8.html">Next: Conclusion and other useful LLVM tidbits</a>
+<a href="OCamlLangImpl8.html">Next: Conclusion and other useful LLVM tidbits</a>
</div>
<!-- *********************************************************************** -->
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>
+ <a href="http://llvm.org/">The LLVM Compiler Infrastructure</a><br>
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
- Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
+ Last modified: $Date$
</address>
</body>
</html>