1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 2 "http://www.w3.org/TR/html4/strict.dtd"> 3 4 <html> 5 <head> 6 <title>Kaleidoscope: Adding JIT and Optimizer Support</title> 7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 8 <meta name="author" content="Chris Lattner"> 9 <meta name="author" content="Erick Tryzelaar"> 10 <link rel="stylesheet" href="../llvm.css" type="text/css"> 11 </head> 12 13 <body> 14 15 <h1>Kaleidoscope: Adding JIT and Optimizer Support</h1> 16 17 <ul> 18 <li><a href="index.html">Up to Tutorial Index</a></li> 19 <li>Chapter 4 20 <ol> 21 <li><a href="#intro">Chapter 4 Introduction</a></li> 22 <li><a href="#trivialconstfold">Trivial Constant Folding</a></li> 23 <li><a href="#optimizerpasses">LLVM Optimization Passes</a></li> 24 <li><a href="#jit">Adding a JIT Compiler</a></li> 25 <li><a href="#code">Full Code Listing</a></li> 26 </ol> 27 </li> 28 <li><a href="OCamlLangImpl5.html">Chapter 5</a>: Extending the Language: Control 29 Flow</li> 30 </ul> 31 32 <div class="doc_author"> 33 <p> 34 Written by <a href="mailto:sabre (a] nondot.org">Chris Lattner</a> 35 and <a href="mailto:idadesub (a] users.sourceforge.net">Erick Tryzelaar</a> 36 </p> 37 </div> 38 39 <!-- *********************************************************************** --> 40 <h2><a name="intro">Chapter 4 Introduction</a></h2> 41 <!-- *********************************************************************** --> 42 43 <div> 44 45 <p>Welcome to Chapter 4 of the "<a href="index.html">Implementing a language 46 with LLVM</a>" tutorial. Chapters 1-3 described the implementation of a simple 47 language and added support for generating LLVM IR. This chapter describes 48 two new techniques: adding optimizer support to your language, and adding JIT 49 compiler support. These additions will demonstrate how to get nice, efficient code 50 for the Kaleidoscope language.</p> 51 52 </div> 53 54 <!-- *********************************************************************** --> 55 <h2><a name="trivialconstfold">Trivial Constant Folding</a></h2> 56 <!-- *********************************************************************** --> 57 58 <div> 59 60 <p><b>Note:</b> the default <tt>IRBuilder</tt> now always includes the constant 61 folding optimisations below.<p> 62 63 <p> 64 Our demonstration for Chapter 3 is elegant and easy to extend. Unfortunately, 65 it does not produce wonderful code. For example, when compiling simple code, 66 we don't get obvious optimizations:</p> 67 68 <div class="doc_code"> 69 <pre> 70 ready> <b>def test(x) 1+2+x;</b> 71 Read function definition: 72 define double @test(double %x) { 73 entry: 74 %addtmp = fadd double 1.000000e+00, 2.000000e+00 75 %addtmp1 = fadd double %addtmp, %x 76 ret double %addtmp1 77 } 78 </pre> 79 </div> 80 81 <p>This code is a very, very literal transcription of the AST built by parsing 82 the input. As such, this transcription lacks optimizations like constant folding 83 (we'd like to get "<tt>add x, 3.0</tt>" in the example above) as well as other 84 more important optimizations. Constant folding, in particular, is a very common 85 and very important optimization: so much so that many language implementors 86 implement constant folding support in their AST representation.</p> 87 88 <p>With LLVM, you don't need this support in the AST. Since all calls to build 89 LLVM IR go through the LLVM builder, it would be nice if the builder itself 90 checked to see if there was a constant folding opportunity when you call it. 91 If so, it could just do the constant fold and return the constant instead of 92 creating an instruction. This is exactly what the <tt>LLVMFoldingBuilder</tt> 93 class does. 94 95 <p>All we did was switch from <tt>LLVMBuilder</tt> to 96 <tt>LLVMFoldingBuilder</tt>. Though we change no other code, we now have all of our 97 instructions implicitly constant folded without us having to do anything 98 about it. For example, the input above now compiles to:</p> 99 100 <div class="doc_code"> 101 <pre> 102 ready> <b>def test(x) 1+2+x;</b> 103 Read function definition: 104 define double @test(double %x) { 105 entry: 106 %addtmp = fadd double 3.000000e+00, %x 107 ret double %addtmp 108 } 109 </pre> 110 </div> 111 112 <p>Well, that was easy :). In practice, we recommend always using 113 <tt>LLVMFoldingBuilder</tt> when generating code like this. It has no 114 "syntactic overhead" for its use (you don't have to uglify your compiler with 115 constant checks everywhere) and it can dramatically reduce the amount of 116 LLVM IR that is generated in some cases (particular for languages with a macro 117 preprocessor or that use a lot of constants).</p> 118 119 <p>On the other hand, the <tt>LLVMFoldingBuilder</tt> is limited by the fact 120 that it does all of its analysis inline with the code as it is built. If you 121 take a slightly more complex example:</p> 122 123 <div class="doc_code"> 124 <pre> 125 ready> <b>def test(x) (1+2+x)*(x+(1+2));</b> 126 ready> Read function definition: 127 define double @test(double %x) { 128 entry: 129 %addtmp = fadd double 3.000000e+00, %x 130 %addtmp1 = fadd double %x, 3.000000e+00 131 %multmp = fmul double %addtmp, %addtmp1 132 ret double %multmp 133 } 134 </pre> 135 </div> 136 137 <p>In this case, the LHS and RHS of the multiplication are the same value. We'd 138 really like to see this generate "<tt>tmp = x+3; result = tmp*tmp;</tt>" instead 139 of computing "<tt>x*3</tt>" twice.</p> 140 141 <p>Unfortunately, no amount of local analysis will be able to detect and correct 142 this. This requires two transformations: reassociation of expressions (to 143 make the add's lexically identical) and Common Subexpression Elimination (CSE) 144 to delete the redundant add instruction. Fortunately, LLVM provides a broad 145 range of optimizations that you can use, in the form of "passes".</p> 146 147 </div> 148 149 <!-- *********************************************************************** --> 150 <h2><a name="optimizerpasses">LLVM Optimization Passes</a></h2> 151 <!-- *********************************************************************** --> 152 153 <div> 154 155 <p>LLVM provides many optimization passes, which do many different sorts of 156 things and have different tradeoffs. Unlike other systems, LLVM doesn't hold 157 to the mistaken notion that one set of optimizations is right for all languages 158 and for all situations. LLVM allows a compiler implementor to make complete 159 decisions about what optimizations to use, in which order, and in what 160 situation.</p> 161 162 <p>As a concrete example, LLVM supports both "whole module" passes, which look 163 across as large of body of code as they can (often a whole file, but if run 164 at link time, this can be a substantial portion of the whole program). It also 165 supports and includes "per-function" passes which just operate on a single 166 function at a time, without looking at other functions. For more information 167 on passes and how they are run, see the <a href="../WritingAnLLVMPass.html">How 168 to Write a Pass</a> document and the <a href="../Passes.html">List of LLVM 169 Passes</a>.</p> 170 171 <p>For Kaleidoscope, we are currently generating functions on the fly, one at 172 a time, as the user types them in. We aren't shooting for the ultimate 173 optimization experience in this setting, but we also want to catch the easy and 174 quick stuff where possible. As such, we will choose to run a few per-function 175 optimizations as the user types the function in. If we wanted to make a "static 176 Kaleidoscope compiler", we would use exactly the code we have now, except that 177 we would defer running the optimizer until the entire file has been parsed.</p> 178 179 <p>In order to get per-function optimizations going, we need to set up a 180 <a href="../WritingAnLLVMPass.html#passmanager">Llvm.PassManager</a> to hold and 181 organize the LLVM optimizations that we want to run. Once we have that, we can 182 add a set of optimizations to run. The code looks like this:</p> 183 184 <div class="doc_code"> 185 <pre> 186 (* Create the JIT. *) 187 let the_execution_engine = ExecutionEngine.create Codegen.the_module in 188 let the_fpm = PassManager.create_function Codegen.the_module in 189 190 (* Set up the optimizer pipeline. Start with registering info about how the 191 * target lays out data structures. *) 192 TargetData.add (ExecutionEngine.target_data the_execution_engine) the_fpm; 193 194 (* Do simple "peephole" optimizations and bit-twiddling optzn. *) 195 add_instruction_combining the_fpm; 196 197 (* reassociate expressions. *) 198 add_reassociation the_fpm; 199 200 (* Eliminate Common SubExpressions. *) 201 add_gvn the_fpm; 202 203 (* Simplify the control flow graph (deleting unreachable blocks, etc). *) 204 add_cfg_simplification the_fpm; 205 206 ignore (PassManager.initialize the_fpm); 207 208 (* Run the main "interpreter loop" now. *) 209 Toplevel.main_loop the_fpm the_execution_engine stream; 210 </pre> 211 </div> 212 213 <p>The meat of the matter here, is the definition of "<tt>the_fpm</tt>". It 214 requires a pointer to the <tt>the_module</tt> to construct itself. Once it is 215 set up, we use a series of "add" calls to add a bunch of LLVM passes. The 216 first pass is basically boilerplate, it adds a pass so that later optimizations 217 know how the data structures in the program are laid out. The 218 "<tt>the_execution_engine</tt>" variable is related to the JIT, which we will 219 get to in the next section.</p> 220 221 <p>In this case, we choose to add 4 optimization passes. The passes we chose 222 here are a pretty standard set of "cleanup" optimizations that are useful for 223 a wide variety of code. I won't delve into what they do but, believe me, 224 they are a good starting place :).</p> 225 226 <p>Once the <tt>Llvm.PassManager.</tt> is set up, we need to make use of it. 227 We do this by running it after our newly created function is constructed (in 228 <tt>Codegen.codegen_func</tt>), but before it is returned to the client:</p> 229 230 <div class="doc_code"> 231 <pre> 232 let codegen_func the_fpm = function 233 ... 234 try 235 let ret_val = codegen_expr body in 236 237 (* Finish off the function. *) 238 let _ = build_ret ret_val builder in 239 240 (* Validate the generated code, checking for consistency. *) 241 Llvm_analysis.assert_valid_function the_function; 242 243 (* Optimize the function. *) 244 let _ = PassManager.run_function the_function the_fpm in 245 246 the_function 247 </pre> 248 </div> 249 250 <p>As you can see, this is pretty straightforward. The <tt>the_fpm</tt> 251 optimizes and updates the LLVM Function* in place, improving (hopefully) its 252 body. With this in place, we can try our test above again:</p> 253 254 <div class="doc_code"> 255 <pre> 256 ready> <b>def test(x) (1+2+x)*(x+(1+2));</b> 257 ready> Read function definition: 258 define double @test(double %x) { 259 entry: 260 %addtmp = fadd double %x, 3.000000e+00 261 %multmp = fmul double %addtmp, %addtmp 262 ret double %multmp 263 } 264 </pre> 265 </div> 266 267 <p>As expected, we now get our nicely optimized code, saving a floating point 268 add instruction from every execution of this function.</p> 269 270 <p>LLVM provides a wide variety of optimizations that can be used in certain 271 circumstances. Some <a href="../Passes.html">documentation about the various 272 passes</a> is available, but it isn't very complete. Another good source of 273 ideas can come from looking at the passes that <tt>llvm-gcc</tt> or 274 <tt>llvm-ld</tt> run to get started. The "<tt>opt</tt>" tool allows you to 275 experiment with passes from the command line, so you can see if they do 276 anything.</p> 277 278 <p>Now that we have reasonable code coming out of our front-end, lets talk about 279 executing it!</p> 280 281 </div> 282 283 <!-- *********************************************************************** --> 284 <h2><a name="jit">Adding a JIT Compiler</a></h2> 285 <!-- *********************************************************************** --> 286 287 <div> 288 289 <p>Code that is available in LLVM IR can have a wide variety of tools 290 applied to it. For example, you can run optimizations on it (as we did above), 291 you can dump it out in textual or binary forms, you can compile the code to an 292 assembly file (.s) for some target, or you can JIT compile it. The nice thing 293 about the LLVM IR representation is that it is the "common currency" between 294 many different parts of the compiler. 295 </p> 296 297 <p>In this section, we'll add JIT compiler support to our interpreter. The 298 basic idea that we want for Kaleidoscope is to have the user enter function 299 bodies as they do now, but immediately evaluate the top-level expressions they 300 type in. For example, if they type in "1 + 2;", we should evaluate and print 301 out 3. If they define a function, they should be able to call it from the 302 command line.</p> 303 304 <p>In order to do this, we first declare and initialize the JIT. This is done 305 by adding a global variable and a call in <tt>main</tt>:</p> 306 307 <div class="doc_code"> 308 <pre> 309 ... 310 let main () = 311 ... 312 <b>(* Create the JIT. *) 313 let the_execution_engine = ExecutionEngine.create Codegen.the_module in</b> 314 ... 315 </pre> 316 </div> 317 318 <p>This creates an abstract "Execution Engine" which can be either a JIT 319 compiler or the LLVM interpreter. LLVM will automatically pick a JIT compiler 320 for you if one is available for your platform, otherwise it will fall back to 321 the interpreter.</p> 322 323 <p>Once the <tt>Llvm_executionengine.ExecutionEngine.t</tt> is created, the JIT 324 is ready to be used. There are a variety of APIs that are useful, but the 325 simplest one is the "<tt>Llvm_executionengine.ExecutionEngine.run_function</tt>" 326 function. This method JIT compiles the specified LLVM Function and returns a 327 function pointer to the generated machine code. In our case, this means that we 328 can change the code that parses a top-level expression to look like this:</p> 329 330 <div class="doc_code"> 331 <pre> 332 (* Evaluate a top-level expression into an anonymous function. *) 333 let e = Parser.parse_toplevel stream in 334 print_endline "parsed a top-level expr"; 335 let the_function = Codegen.codegen_func the_fpm e in 336 dump_value the_function; 337 338 (* JIT the function, returning a function pointer. *) 339 let result = ExecutionEngine.run_function the_function [||] 340 the_execution_engine in 341 342 print_string "Evaluated to "; 343 print_float (GenericValue.as_float Codegen.double_type result); 344 print_newline (); 345 </pre> 346 </div> 347 348 <p>Recall that we compile top-level expressions into a self-contained LLVM 349 function that takes no arguments and returns the computed double. Because the 350 LLVM JIT compiler matches the native platform ABI, this means that you can just 351 cast the result pointer to a function pointer of that type and call it directly. 352 This means, there is no difference between JIT compiled code and native machine 353 code that is statically linked into your application.</p> 354 355 <p>With just these two changes, lets see how Kaleidoscope works now!</p> 356 357 <div class="doc_code"> 358 <pre> 359 ready> <b>4+5;</b> 360 define double @""() { 361 entry: 362 ret double 9.000000e+00 363 } 364 365 <em>Evaluated to 9.000000</em> 366 </pre> 367 </div> 368 369 <p>Well this looks like it is basically working. The dump of the function 370 shows the "no argument function that always returns double" that we synthesize 371 for each top level expression that is typed in. This demonstrates very basic 372 functionality, but can we do more?</p> 373 374 <div class="doc_code"> 375 <pre> 376 ready> <b>def testfunc(x y) x + y*2; </b> 377 Read function definition: 378 define double @testfunc(double %x, double %y) { 379 entry: 380 %multmp = fmul double %y, 2.000000e+00 381 %addtmp = fadd double %multmp, %x 382 ret double %addtmp 383 } 384 385 ready> <b>testfunc(4, 10);</b> 386 define double @""() { 387 entry: 388 %calltmp = call double @testfunc(double 4.000000e+00, double 1.000000e+01) 389 ret double %calltmp 390 } 391 392 <em>Evaluated to 24.000000</em> 393 </pre> 394 </div> 395 396 <p>This illustrates that we can now call user code, but there is something a bit 397 subtle going on here. Note that we only invoke the JIT on the anonymous 398 functions that <em>call testfunc</em>, but we never invoked it 399 on <em>testfunc</em> itself. What actually happened here is that the JIT 400 scanned for all non-JIT'd functions transitively called from the anonymous 401 function and compiled all of them before returning 402 from <tt>run_function</tt>.</p> 403 404 <p>The JIT provides a number of other more advanced interfaces for things like 405 freeing allocated machine code, rejit'ing functions to update them, etc. 406 However, even with this simple code, we get some surprisingly powerful 407 capabilities - check this out (I removed the dump of the anonymous functions, 408 you should get the idea by now :) :</p> 409 410 <div class="doc_code"> 411 <pre> 412 ready> <b>extern sin(x);</b> 413 Read extern: 414 declare double @sin(double) 415 416 ready> <b>extern cos(x);</b> 417 Read extern: 418 declare double @cos(double) 419 420 ready> <b>sin(1.0);</b> 421 <em>Evaluated to 0.841471</em> 422 423 ready> <b>def foo(x) sin(x)*sin(x) + cos(x)*cos(x);</b> 424 Read function definition: 425 define double @foo(double %x) { 426 entry: 427 %calltmp = call double @sin(double %x) 428 %multmp = fmul double %calltmp, %calltmp 429 %calltmp2 = call double @cos(double %x) 430 %multmp4 = fmul double %calltmp2, %calltmp2 431 %addtmp = fadd double %multmp, %multmp4 432 ret double %addtmp 433 } 434 435 ready> <b>foo(4.0);</b> 436 <em>Evaluated to 1.000000</em> 437 </pre> 438 </div> 439 440 <p>Whoa, how does the JIT know about sin and cos? The answer is surprisingly 441 simple: in this example, the JIT started execution of a function and got to a 442 function call. It realized that the function was not yet JIT compiled and 443 invoked the standard set of routines to resolve the function. In this case, 444 there is no body defined for the function, so the JIT ended up calling 445 "<tt>dlsym("sin")</tt>" on the Kaleidoscope process itself. Since 446 "<tt>sin</tt>" is defined within the JIT's address space, it simply patches up 447 calls in the module to call the libm version of <tt>sin</tt> directly.</p> 448 449 <p>The LLVM JIT provides a number of interfaces (look in the 450 <tt>llvm_executionengine.mli</tt> file) for controlling how unknown functions 451 get resolved. It allows you to establish explicit mappings between IR objects 452 and addresses (useful for LLVM global variables that you want to map to static 453 tables, for example), allows you to dynamically decide on the fly based on the 454 function name, and even allows you to have the JIT compile functions lazily the 455 first time they're called.</p> 456 457 <p>One interesting application of this is that we can now extend the language 458 by writing arbitrary C code to implement operations. For example, if we add: 459 </p> 460 461 <div class="doc_code"> 462 <pre> 463 /* putchard - putchar that takes a double and returns 0. */ 464 extern "C" 465 double putchard(double X) { 466 putchar((char)X); 467 return 0; 468 } 469 </pre> 470 </div> 471 472 <p>Now we can produce simple output to the console by using things like: 473 "<tt>extern putchard(x); putchard(120);</tt>", which prints a lowercase 'x' on 474 the console (120 is the ASCII code for 'x'). Similar code could be used to 475 implement file I/O, console input, and many other capabilities in 476 Kaleidoscope.</p> 477 478 <p>This completes the JIT and optimizer chapter of the Kaleidoscope tutorial. At 479 this point, we can compile a non-Turing-complete programming language, optimize 480 and JIT compile it in a user-driven way. Next up we'll look into <a 481 href="OCamlLangImpl5.html">extending the language with control flow 482 constructs</a>, tackling some interesting LLVM IR issues along the way.</p> 483 484 </div> 485 486 <!-- *********************************************************************** --> 487 <h2><a name="code">Full Code Listing</a></h2> 488 <!-- *********************************************************************** --> 489 490 <div> 491 492 <p> 493 Here is the complete code listing for our running example, enhanced with the 494 LLVM JIT and optimizer. To build this example, use: 495 </p> 496 497 <div class="doc_code"> 498 <pre> 499 # Compile 500 ocamlbuild toy.byte 501 # Run 502 ./toy.byte 503 </pre> 504 </div> 505 506 <p>Here is the code:</p> 507 508 <dl> 509 <dt>_tags:</dt> 510 <dd class="doc_code"> 511 <pre> 512 <{lexer,parser}.ml>: use_camlp4, pp(camlp4of) 513 <*.{byte,native}>: g++, use_llvm, use_llvm_analysis 514 <*.{byte,native}>: use_llvm_executionengine, use_llvm_target 515 <*.{byte,native}>: use_llvm_scalar_opts, use_bindings 516 </pre> 517 </dd> 518 519 <dt>myocamlbuild.ml:</dt> 520 <dd class="doc_code"> 521 <pre> 522 open Ocamlbuild_plugin;; 523 524 ocaml_lib ~extern:true "llvm";; 525 ocaml_lib ~extern:true "llvm_analysis";; 526 ocaml_lib ~extern:true "llvm_executionengine";; 527 ocaml_lib ~extern:true "llvm_target";; 528 ocaml_lib ~extern:true "llvm_scalar_opts";; 529 530 flag ["link"; "ocaml"; "g++"] (S[A"-cc"; A"g++"]);; 531 dep ["link"; "ocaml"; "use_bindings"] ["bindings.o"];; 532 </pre> 533 </dd> 534 535 <dt>token.ml:</dt> 536 <dd class="doc_code"> 537 <pre> 538 (*===----------------------------------------------------------------------=== 539 * Lexer Tokens 540 *===----------------------------------------------------------------------===*) 541 542 (* The lexer returns these 'Kwd' if it is an unknown character, otherwise one of 543 * these others for known things. *) 544 type token = 545 (* commands *) 546 | Def | Extern 547 548 (* primary *) 549 | Ident of string | Number of float 550 551 (* unknown *) 552 | Kwd of char 553 </pre> 554 </dd> 555 556 <dt>lexer.ml:</dt> 557 <dd class="doc_code"> 558 <pre> 559 (*===----------------------------------------------------------------------=== 560 * Lexer 561 *===----------------------------------------------------------------------===*) 562 563 let rec lex = parser 564 (* Skip any whitespace. *) 565 | [< ' (' ' | '\n' | '\r' | '\t'); stream >] -> lex stream 566 567 (* identifier: [a-zA-Z][a-zA-Z0-9] *) 568 | [< ' ('A' .. 'Z' | 'a' .. 'z' as c); stream >] -> 569 let buffer = Buffer.create 1 in 570 Buffer.add_char buffer c; 571 lex_ident buffer stream 572 573 (* number: [0-9.]+ *) 574 | [< ' ('0' .. '9' as c); stream >] -> 575 let buffer = Buffer.create 1 in 576 Buffer.add_char buffer c; 577 lex_number buffer stream 578 579 (* Comment until end of line. *) 580 | [< ' ('#'); stream >] -> 581 lex_comment stream 582 583 (* Otherwise, just return the character as its ascii value. *) 584 | [< 'c; stream >] -> 585 [< 'Token.Kwd c; lex stream >] 586 587 (* end of stream. *) 588 | [< >] -> [< >] 589 590 and lex_number buffer = parser 591 | [< ' ('0' .. '9' | '.' as c); stream >] -> 592 Buffer.add_char buffer c; 593 lex_number buffer stream 594 | [< stream=lex >] -> 595 [< 'Token.Number (float_of_string (Buffer.contents buffer)); stream >] 596 597 and lex_ident buffer = parser 598 | [< ' ('A' .. 'Z' | 'a' .. 'z' | '0' .. '9' as c); stream >] -> 599 Buffer.add_char buffer c; 600 lex_ident buffer stream 601 | [< stream=lex >] -> 602 match Buffer.contents buffer with 603 | "def" -> [< 'Token.Def; stream >] 604 | "extern" -> [< 'Token.Extern; stream >] 605 | id -> [< 'Token.Ident id; stream >] 606 607 and lex_comment = parser 608 | [< ' ('\n'); stream=lex >] -> stream 609 | [< 'c; e=lex_comment >] -> e 610 | [< >] -> [< >] 611 </pre> 612 </dd> 613 614 <dt>ast.ml:</dt> 615 <dd class="doc_code"> 616 <pre> 617 (*===----------------------------------------------------------------------=== 618 * Abstract Syntax Tree (aka Parse Tree) 619 *===----------------------------------------------------------------------===*) 620 621 (* expr - Base type for all expression nodes. *) 622 type expr = 623 (* variant for numeric literals like "1.0". *) 624 | Number of float 625 626 (* variant for referencing a variable, like "a". *) 627 | Variable of string 628 629 (* variant for a binary operator. *) 630 | Binary of char * expr * expr 631 632 (* variant for function calls. *) 633 | Call of string * expr array 634 635 (* proto - This type represents the "prototype" for a function, which captures 636 * its name, and its argument names (thus implicitly the number of arguments the 637 * function takes). *) 638 type proto = Prototype of string * string array 639 640 (* func - This type represents a function definition itself. *) 641 type func = Function of proto * expr 642 </pre> 643 </dd> 644 645 <dt>parser.ml:</dt> 646 <dd class="doc_code"> 647 <pre> 648 (*===---------------------------------------------------------------------=== 649 * Parser 650 *===---------------------------------------------------------------------===*) 651 652 (* binop_precedence - This holds the precedence for each binary operator that is 653 * defined *) 654 let binop_precedence:(char, int) Hashtbl.t = Hashtbl.create 10 655 656 (* precedence - Get the precedence of the pending binary operator token. *) 657 let precedence c = try Hashtbl.find binop_precedence c with Not_found -> -1 658 659 (* primary 660 * ::= identifier 661 * ::= numberexpr 662 * ::= parenexpr *) 663 let rec parse_primary = parser 664 (* numberexpr ::= number *) 665 | [< 'Token.Number n >] -> Ast.Number n 666 667 (* parenexpr ::= '(' expression ')' *) 668 | [< 'Token.Kwd '('; e=parse_expr; 'Token.Kwd ')' ?? "expected ')'" >] -> e 669 670 (* identifierexpr 671 * ::= identifier 672 * ::= identifier '(' argumentexpr ')' *) 673 | [< 'Token.Ident id; stream >] -> 674 let rec parse_args accumulator = parser 675 | [< e=parse_expr; stream >] -> 676 begin parser 677 | [< 'Token.Kwd ','; e=parse_args (e :: accumulator) >] -> e 678 | [< >] -> e :: accumulator 679 end stream 680 | [< >] -> accumulator 681 in 682 let rec parse_ident id = parser 683 (* Call. *) 684 | [< 'Token.Kwd '('; 685 args=parse_args []; 686 'Token.Kwd ')' ?? "expected ')'">] -> 687 Ast.Call (id, Array.of_list (List.rev args)) 688 689 (* Simple variable ref. *) 690 | [< >] -> Ast.Variable id 691 in 692 parse_ident id stream 693 694 | [< >] -> raise (Stream.Error "unknown token when expecting an expression.") 695 696 (* binoprhs 697 * ::= ('+' primary)* *) 698 and parse_bin_rhs expr_prec lhs stream = 699 match Stream.peek stream with 700 (* If this is a binop, find its precedence. *) 701 | Some (Token.Kwd c) when Hashtbl.mem binop_precedence c -> 702 let token_prec = precedence c in 703 704 (* If this is a binop that binds at least as tightly as the current binop, 705 * consume it, otherwise we are done. *) 706 if token_prec < expr_prec then lhs else begin 707 (* Eat the binop. *) 708 Stream.junk stream; 709 710 (* Parse the primary expression after the binary operator. *) 711 let rhs = parse_primary stream in 712 713 (* Okay, we know this is a binop. *) 714 let rhs = 715 match Stream.peek stream with 716 | Some (Token.Kwd c2) -> 717 (* If BinOp binds less tightly with rhs than the operator after 718 * rhs, let the pending operator take rhs as its lhs. *) 719 let next_prec = precedence c2 in 720 if token_prec < next_prec 721 then parse_bin_rhs (token_prec + 1) rhs stream 722 else rhs 723 | _ -> rhs 724 in 725 726 (* Merge lhs/rhs. *) 727 let lhs = Ast.Binary (c, lhs, rhs) in 728 parse_bin_rhs expr_prec lhs stream 729 end 730 | _ -> lhs 731 732 (* expression 733 * ::= primary binoprhs *) 734 and parse_expr = parser 735 | [< lhs=parse_primary; stream >] -> parse_bin_rhs 0 lhs stream 736 737 (* prototype 738 * ::= id '(' id* ')' *) 739 let parse_prototype = 740 let rec parse_args accumulator = parser 741 | [< 'Token.Ident id; e=parse_args (id::accumulator) >] -> e 742 | [< >] -> accumulator 743 in 744 745 parser 746 | [< 'Token.Ident id; 747 'Token.Kwd '(' ?? "expected '(' in prototype"; 748 args=parse_args []; 749 'Token.Kwd ')' ?? "expected ')' in prototype" >] -> 750 (* success. *) 751 Ast.Prototype (id, Array.of_list (List.rev args)) 752 753 | [< >] -> 754 raise (Stream.Error "expected function name in prototype") 755 756 (* definition ::= 'def' prototype expression *) 757 let parse_definition = parser 758 | [< 'Token.Def; p=parse_prototype; e=parse_expr >] -> 759 Ast.Function (p, e) 760 761 (* toplevelexpr ::= expression *) 762 let parse_toplevel = parser 763 | [< e=parse_expr >] -> 764 (* Make an anonymous proto. *) 765 Ast.Function (Ast.Prototype ("", [||]), e) 766 767 (* external ::= 'extern' prototype *) 768 let parse_extern = parser 769 | [< 'Token.Extern; e=parse_prototype >] -> e 770 </pre> 771 </dd> 772 773 <dt>codegen.ml:</dt> 774 <dd class="doc_code"> 775 <pre> 776 (*===----------------------------------------------------------------------=== 777 * Code Generation 778 *===----------------------------------------------------------------------===*) 779 780 open Llvm 781 782 exception Error of string 783 784 let context = global_context () 785 let the_module = create_module context "my cool jit" 786 let builder = builder context 787 let named_values:(string, llvalue) Hashtbl.t = Hashtbl.create 10 788 let double_type = double_type context 789 790 let rec codegen_expr = function 791 | Ast.Number n -> const_float double_type n 792 | Ast.Variable name -> 793 (try Hashtbl.find named_values name with 794 | Not_found -> raise (Error "unknown variable name")) 795 | Ast.Binary (op, lhs, rhs) -> 796 let lhs_val = codegen_expr lhs in 797 let rhs_val = codegen_expr rhs in 798 begin 799 match op with 800 | '+' -> build_add lhs_val rhs_val "addtmp" builder 801 | '-' -> build_sub lhs_val rhs_val "subtmp" builder 802 | '*' -> build_mul lhs_val rhs_val "multmp" builder 803 | '<' -> 804 (* Convert bool 0/1 to double 0.0 or 1.0 *) 805 let i = build_fcmp Fcmp.Ult lhs_val rhs_val "cmptmp" builder in 806 build_uitofp i double_type "booltmp" builder 807 | _ -> raise (Error "invalid binary operator") 808 end 809 | Ast.Call (callee, args) -> 810 (* Look up the name in the module table. *) 811 let callee = 812 match lookup_function callee the_module with 813 | Some callee -> callee 814 | None -> raise (Error "unknown function referenced") 815 in 816 let params = params callee in 817 818 (* If argument mismatch error. *) 819 if Array.length params == Array.length args then () else 820 raise (Error "incorrect # arguments passed"); 821 let args = Array.map codegen_expr args in 822 build_call callee args "calltmp" builder 823 824 let codegen_proto = function 825 | Ast.Prototype (name, args) -> 826 (* Make the function type: double(double,double) etc. *) 827 let doubles = Array.make (Array.length args) double_type in 828 let ft = function_type double_type doubles in 829 let f = 830 match lookup_function name the_module with 831 | None -> declare_function name ft the_module 832 833 (* If 'f' conflicted, there was already something named 'name'. If it 834 * has a body, don't allow redefinition or reextern. *) 835 | Some f -> 836 (* If 'f' already has a body, reject this. *) 837 if block_begin f <> At_end f then 838 raise (Error "redefinition of function"); 839 840 (* If 'f' took a different number of arguments, reject. *) 841 if element_type (type_of f) <> ft then 842 raise (Error "redefinition of function with different # args"); 843 f 844 in 845 846 (* Set names for all arguments. *) 847 Array.iteri (fun i a -> 848 let n = args.(i) in 849 set_value_name n a; 850 Hashtbl.add named_values n a; 851 ) (params f); 852 f 853 854 let codegen_func the_fpm = function 855 | Ast.Function (proto, body) -> 856 Hashtbl.clear named_values; 857 let the_function = codegen_proto proto in 858 859 (* Create a new basic block to start insertion into. *) 860 let bb = append_block context "entry" the_function in 861 position_at_end bb builder; 862 863 try 864 let ret_val = codegen_expr body in 865 866 (* Finish off the function. *) 867 let _ = build_ret ret_val builder in 868 869 (* Validate the generated code, checking for consistency. *) 870 Llvm_analysis.assert_valid_function the_function; 871 872 (* Optimize the function. *) 873 let _ = PassManager.run_function the_function the_fpm in 874 875 the_function 876 with e -> 877 delete_function the_function; 878 raise e 879 </pre> 880 </dd> 881 882 <dt>toplevel.ml:</dt> 883 <dd class="doc_code"> 884 <pre> 885 (*===----------------------------------------------------------------------=== 886 * Top-Level parsing and JIT Driver 887 *===----------------------------------------------------------------------===*) 888 889 open Llvm 890 open Llvm_executionengine 891 892 (* top ::= definition | external | expression | ';' *) 893 let rec main_loop the_fpm the_execution_engine stream = 894 match Stream.peek stream with 895 | None -> () 896 897 (* ignore top-level semicolons. *) 898 | Some (Token.Kwd ';') -> 899 Stream.junk stream; 900 main_loop the_fpm the_execution_engine stream 901 902 | Some token -> 903 begin 904 try match token with 905 | Token.Def -> 906 let e = Parser.parse_definition stream in 907 print_endline "parsed a function definition."; 908 dump_value (Codegen.codegen_func the_fpm e); 909 | Token.Extern -> 910 let e = Parser.parse_extern stream in 911 print_endline "parsed an extern."; 912 dump_value (Codegen.codegen_proto e); 913 | _ -> 914 (* Evaluate a top-level expression into an anonymous function. *) 915 let e = Parser.parse_toplevel stream in 916 print_endline "parsed a top-level expr"; 917 let the_function = Codegen.codegen_func the_fpm e in 918 dump_value the_function; 919 920 (* JIT the function, returning a function pointer. *) 921 let result = ExecutionEngine.run_function the_function [||] 922 the_execution_engine in 923 924 print_string "Evaluated to "; 925 print_float (GenericValue.as_float Codegen.double_type result); 926 print_newline (); 927 with Stream.Error s | Codegen.Error s -> 928 (* Skip token for error recovery. *) 929 Stream.junk stream; 930 print_endline s; 931 end; 932 print_string "ready> "; flush stdout; 933 main_loop the_fpm the_execution_engine stream 934 </pre> 935 </dd> 936 937 <dt>toy.ml:</dt> 938 <dd class="doc_code"> 939 <pre> 940 (*===----------------------------------------------------------------------=== 941 * Main driver code. 942 *===----------------------------------------------------------------------===*) 943 944 open Llvm 945 open Llvm_executionengine 946 open Llvm_target 947 open Llvm_scalar_opts 948 949 let main () = 950 ignore (initialize_native_target ()); 951 952 (* Install standard binary operators. 953 * 1 is the lowest precedence. *) 954 Hashtbl.add Parser.binop_precedence '<' 10; 955 Hashtbl.add Parser.binop_precedence '+' 20; 956 Hashtbl.add Parser.binop_precedence '-' 20; 957 Hashtbl.add Parser.binop_precedence '*' 40; (* highest. *) 958 959 (* Prime the first token. *) 960 print_string "ready> "; flush stdout; 961 let stream = Lexer.lex (Stream.of_channel stdin) in 962 963 (* Create the JIT. *) 964 let the_execution_engine = ExecutionEngine.create Codegen.the_module in 965 let the_fpm = PassManager.create_function Codegen.the_module in 966 967 (* Set up the optimizer pipeline. Start with registering info about how the 968 * target lays out data structures. *) 969 TargetData.add (ExecutionEngine.target_data the_execution_engine) the_fpm; 970 971 (* Do simple "peephole" optimizations and bit-twiddling optzn. *) 972 add_instruction_combination the_fpm; 973 974 (* reassociate expressions. *) 975 add_reassociation the_fpm; 976 977 (* Eliminate Common SubExpressions. *) 978 add_gvn the_fpm; 979 980 (* Simplify the control flow graph (deleting unreachable blocks, etc). *) 981 add_cfg_simplification the_fpm; 982 983 ignore (PassManager.initialize the_fpm); 984 985 (* Run the main "interpreter loop" now. *) 986 Toplevel.main_loop the_fpm the_execution_engine stream; 987 988 (* Print out all the generated code. *) 989 dump_module Codegen.the_module 990 ;; 991 992 main () 993 </pre> 994 </dd> 995 996 <dt>bindings.c</dt> 997 <dd class="doc_code"> 998 <pre> 999 #include <stdio.h> 1000 1001 /* putchard - putchar that takes a double and returns 0. */ 1002 extern double putchard(double X) { 1003 putchar((char)X); 1004 return 0; 1005 } 1006 </pre> 1007 </dd> 1008 </dl> 1009 1010 <a href="OCamlLangImpl5.html">Next: Extending the language: control flow</a> 1011 </div> 1012 1013 <!-- *********************************************************************** --> 1014 <hr> 1015 <address> 1016 <a href="http://jigsaw.w3.org/css-validator/check/referer"><img 1017 src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"></a> 1018 <a href="http://validator.w3.org/check/referer"><img 1019 src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"></a> 1020 1021 <a href="mailto:sabre (a] nondot.org">Chris Lattner</a><br> 1022 <a href="mailto:idadesub (a] users.sourceforge.net">Erick Tryzelaar</a><br> 1023 <a href="http://llvm.org/">The LLVM Compiler Infrastructure</a><br> 1024 Last modified: $Date: 2011-04-22 20:30:22 -0400 (Fri, 22 Apr 2011) $ 1025 </address> 1026 </body> 1027 </html> 1028