X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=docs%2Ftutorial%2FOCamlLangImpl7.html;h=51986b51a11660d2e4414147ae6e8816b1bb1349;hb=5381cbf4f4466e73df870e20383a0b4478bca33e;hp=411e040b93d2cfaa111c68f3199ef6c01e055998;hpb=126d86b9f930e36c37f2bed89e0612a49165ffb5;p=oota-llvm.git diff --git a/docs/tutorial/OCamlLangImpl7.html b/docs/tutorial/OCamlLangImpl7.html index 411e040b93d..51986b51a11 100644 --- a/docs/tutorial/OCamlLangImpl7.html +++ b/docs/tutorial/OCamlLangImpl7.html @@ -13,7 +13,7 @@ -
Kaleidoscope: Extending the Language: Mutable Variables
+

Kaleidoscope: Extending the Language: Mutable Variables

@@ -42,10 +42,10 @@ -
Chapter 7 Introduction
+

Chapter 7 Introduction

-
+

Welcome to Chapter 7 of the "Implementing a language with LLVM" tutorial. In chapters 1 through 6, we've built a very @@ -70,10 +70,10 @@ support for this, though the way it works is a bit unexpected for some.

-
Why is this a hard problem?
+

Why is this a hard problem?

-
+

To understand why mutable variables cause complexities in SSA construction, @@ -144,10 +144,10 @@ logic.

- +

Memory in LLVM

-
+

The 'trick' here is that while LLVM does require all register values to be in SSA form, it does not require (or permit) memory objects to be in SSA form. @@ -325,11 +325,10 @@ variables now!

- +

Mutable Variables in Kaleidoscope

-
+

Now that we know the sort of problem we want to tackle, lets see what this looks like in the context of our little Kaleidoscope language. We're going to @@ -382,11 +381,10 @@ Kaleidoscope to support new variable definitions.

- +

Adjusting Existing Variables for Mutation

-
+

The symbol table in Kaleidoscope is managed at code generation time by the @@ -543,7 +541,7 @@ good codegen once again:

 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. *)
@@ -581,12 +579,12 @@ then:    ; preds = %entry
 
 else:    ; preds = %entry
   %x3 = load double* %x1
-  %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)
   %x4 = load double* %x1
-  %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
@@ -619,11 +617,11 @@ then:
   br 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
   br label %ifcont
 
 ifcont:    ; preds = %else, %then
@@ -649,11 +647,11 @@ entry:
   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:
@@ -672,10 +670,10 @@ we'll add the assignment operator.

- +

New Assignment Operator

-
+

With our current framework, adding a new assignment operator is really simple. We will parse it just like any other binary operator, but handle it @@ -773,11 +771,10 @@ add this next!

- +

User-defined Local Variables

-
+

Adding var/in is just like any other other extensions we made to Kaleidoscope: we extend the lexer, the parser, the AST and the code generator. @@ -956,10 +953,10 @@ anywhere in sight.

- +

Full Code Listing

-
+

Here is the complete code listing for our running example, enhanced with mutable @@ -999,7 +996,7 @@ ocaml_lib ~extern:true "llvm_executionengine";; ocaml_lib ~extern:true "llvm_target";; ocaml_lib ~extern:true "llvm_scalar_opts";; -flag ["link"; "ocaml"; "g++"] (S[A"-cc"; A"g++"]);; +flag ["link"; "ocaml"; "g++"] (S[A"-cc"; A"g++"; A"-cclib"; A"-rdynamic"]);; dep ["link"; "ocaml"; "use_bindings"] ["bindings.o"];; @@ -1388,6 +1385,7 @@ let context = global_context () let the_module = create_module context "my cool jit" let builder = builder context let named_values:(string, llvalue) Hashtbl.t = Hashtbl.create 10 +let double_type = double_type context (* Create an alloca instruction in the entry block of the function. This * is used for mutable variables etc. *) @@ -1482,7 +1480,7 @@ let rec codegen_expr = function 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; @@ -1494,7 +1492,7 @@ let rec codegen_expr = function 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 @@ -1503,7 +1501,7 @@ let rec codegen_expr = function 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 @@ -1555,7 +1553,7 @@ let rec codegen_expr = function (* 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. *) @@ -1599,7 +1597,7 @@ let rec codegen_expr = function 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); @@ -1723,7 +1721,7 @@ let codegen_func the_fpm = function 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 @@ -1791,7 +1789,7 @@ let rec main_loop the_fpm the_execution_engine stream = 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. *) @@ -1816,6 +1814,8 @@ open Llvm_target open Llvm_scalar_opts let main () = + ignore (initialize_native_target ()); + (* Install standard binary operators. * 1 is the lowest precedence. *) Hashtbl.add Parser.binop_precedence '=' 2; @@ -1829,9 +1829,8 @@ let main () = 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. *) @@ -1841,7 +1840,7 @@ let main () = 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; @@ -1885,7 +1884,7 @@ extern double printd(double X) { -Next: Conclusion and other useful LLVM tidbits +Next: Conclusion and other useful LLVM tidbits

@@ -1897,9 +1896,9 @@ extern double printd(double X) { src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"> Chris Lattner
- The LLVM Compiler Infrastructure
+ The LLVM Compiler Infrastructure
Erick Tryzelaar
- Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $ + Last modified: $Date$