xref: /aosp_15_r20/external/llvm/docs/tutorial/OCamlLangImpl4.rst (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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