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