blob: 0d024467d1dfb7370f622e5b81647abe1b45d889 [file] [log] [blame]
Chris Lattner2e902042007-10-22 07:01:42 +00001<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
2 "http://www.w3.org/TR/html4/strict.dtd">
3
4<html>
5<head>
6 <title>Kaleidoscope: Implementing code generation to LLVM IR</title>
7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
8 <meta name="author" content="Chris Lattner">
9 <link rel="stylesheet" href="../llvm.css" type="text/css">
10</head>
11
12<body>
13
14<div class="doc_title">Kaleidoscope: Code generation to LLVM IR</div>
15
Chris Lattner128eb862007-11-05 19:06:59 +000016<ul>
Chris Lattner0e555b12007-11-05 20:04:56 +000017<li><a href="index.html">Up to Tutorial Index</a></li>
Chris Lattner128eb862007-11-05 19:06:59 +000018<li>Chapter 3
19 <ol>
20 <li><a href="#intro">Chapter 3 Introduction</a></li>
21 <li><a href="#basics">Code Generation setup</a></li>
22 <li><a href="#exprs">Expression Code Generation</a></li>
23 <li><a href="#funcs">Function Code Generation</a></li>
24 <li><a href="#driver">Driver Changes and Closing Thoughts</a></li>
25 <li><a href="#code">Full Code Listing</a></li>
26 </ol>
27</li>
Chris Lattner0e555b12007-11-05 20:04:56 +000028<li><a href="LangImpl4.html">Chapter 4</a>: Adding JIT and Optimizer
29Support</li>
Chris Lattner128eb862007-11-05 19:06:59 +000030</ul>
31
Chris Lattner2e902042007-10-22 07:01:42 +000032<div class="doc_author">
33 <p>Written by <a href="mailto:sabre@nondot.org">Chris Lattner</a></p>
34</div>
35
36<!-- *********************************************************************** -->
Chris Lattner128eb862007-11-05 19:06:59 +000037<div class="doc_section"><a name="intro">Chapter 3 Introduction</a></div>
Chris Lattner2e902042007-10-22 07:01:42 +000038<!-- *********************************************************************** -->
39
40<div class="doc_text">
41
Chris Lattner128eb862007-11-05 19:06:59 +000042<p>Welcome to Chapter 3 of the "<a href="index.html">Implementing a language
43with LLVM</a>" tutorial. This chapter shows you how to transform the <a
Chris Lattner2e902042007-10-22 07:01:42 +000044href="LangImpl2.html">Abstract Syntax Tree built in Chapter 2</a> into LLVM IR.
45This will teach you a little bit about how LLVM does things, as well as
46demonstrate how easy it is to use. It's much more work to build a lexer and
47parser than it is to generate LLVM IR code.
48</p>
49
50</div>
51
52<!-- *********************************************************************** -->
53<div class="doc_section"><a name="basics">Code Generation setup</a></div>
54<!-- *********************************************************************** -->
55
56<div class="doc_text">
57
58<p>
59In order to generate LLVM IR, we want some simple setup to get started. First,
60we define virtual codegen methods in each AST class:</p>
61
62<div class="doc_code">
63<pre>
64/// ExprAST - Base class for all expression nodes.
65class ExprAST {
66public:
67 virtual ~ExprAST() {}
Chris Lattnercac21352007-11-05 19:25:14 +000068 <b>virtual Value *Codegen() = 0;</b>
Chris Lattner2e902042007-10-22 07:01:42 +000069};
70
71/// NumberExprAST - Expression class for numeric literals like "1.0".
72class NumberExprAST : public ExprAST {
73 double Val;
74public:
Chris Lattner28571ed2007-10-23 04:27:44 +000075 explicit NumberExprAST(double val) : Val(val) {}
Chris Lattnercac21352007-11-05 19:25:14 +000076 <b>virtual Value *Codegen();</b>
Chris Lattner2e902042007-10-22 07:01:42 +000077};
78...
79</pre>
80</div>
81
Chris Lattner28571ed2007-10-23 04:27:44 +000082<p>The Codegen() method says to emit IR for that AST node and all things it
83depends on, and they all return an LLVM Value object.
84"Value" is the class used to represent a "<a
85href="http://en.wikipedia.org/wiki/Static_single_assignment_form">Static Single
86Assignment (SSA)</a> register" or "SSA value" in LLVM. The most distinct aspect
87of SSA values is that their value is computed as the related instruction
88executes, and it does not get a new value until (and if) the instruction
89re-executes. In order words, there is no way to "change" an SSA value. For
90more information, please read up on <a
91href="http://en.wikipedia.org/wiki/Static_single_assignment_form">Static Single
92Assignment</a> - the concepts are really quite natural once you grok them.</p>
93
Chris Lattnercac21352007-11-05 19:25:14 +000094<p>Note that instead of adding virtual methods to the ExprAST class hierarchy,
95it could also make sense to use a visitor pattern or some other way to model
96this. Again, this tutorial won't dwell on good software engineering practices:
Chris Lattnerbb80f932007-11-05 19:33:52 +000097for our purposes, adding a virtual method is simplest.</p>
Chris Lattnercac21352007-11-05 19:25:14 +000098
Chris Lattner28571ed2007-10-23 04:27:44 +000099<p>The
Chris Lattner2e902042007-10-22 07:01:42 +0000100second thing we want is an "Error" method like we used for parser, which will
101be used to report errors found during code generation (for example, use of an
102undeclared parameter):</p>
103
104<div class="doc_code">
105<pre>
106Value *ErrorV(const char *Str) { Error(Str); return 0; }
107
108static Module *TheModule;
109static LLVMBuilder Builder;
110static std::map&lt;std::string, Value*&gt; NamedValues;
111</pre>
112</div>
113
114<p>The static variables will be used during code generation. <tt>TheModule</tt>
115is the LLVM construct that contains all of the functions and global variables in
116a chunk of code. In many ways, it is the top-level structure that the LLVM IR
117uses to contain code.</p>
118
119<p>The <tt>Builder</tt> object is a helper object that makes it easy to generate
Chris Lattnerf6e53df2007-11-05 18:02:15 +0000120LLVM instructions. Instances of the <a
121href="http://llvm.org/doxygen/LLVMBuilder_8h-source.html"><tt>LLVMBuilder</tt>
122class</a> keeps track of the current place to
Chris Lattner2e902042007-10-22 07:01:42 +0000123insert instructions and has methods to create new instructions.</p>
124
125<p>The <tt>NamedValues</tt> map keeps track of which values are defined in the
126current scope and what their LLVM representation is. In this form of
127Kaleidoscope, the only things that can be referenced are function parameters.
128As such, function parameters will be in this map when generating code for their
129function body.</p>
130
131<p>
132With these basics in place, we can start talking about how to generate code for
133each expression. Note that this assumes that the <tt>Builder</tt> has been set
134up to generate code <em>into</em> something. For now, we'll assume that this
135has already been done, and we'll just use it to emit code.
136</p>
137
138</div>
139
140<!-- *********************************************************************** -->
141<div class="doc_section"><a name="exprs">Expression Code Generation</a></div>
142<!-- *********************************************************************** -->
143
144<div class="doc_text">
145
146<p>Generating LLVM code for expression nodes is very straight-forward: less
147than 45 lines of commented code for all four of our expression nodes. First,
148we'll do numeric literals:</p>
149
150<div class="doc_code">
151<pre>
152Value *NumberExprAST::Codegen() {
153 return ConstantFP::get(Type::DoubleTy, APFloat(Val));
154}
155</pre>
156</div>
157
Chris Lattnerd3f0cdd2007-10-23 04:51:30 +0000158<p>In the LLVM IR, numeric constants are represented with the
159<tt>ConstantFP</tt> class, which holds the numeric value in an <tt>APFloat</tt>
160internally (<tt>APFloat</tt> has the capability of holding floating point
161constants of <em>A</em>rbitrary <em>P</em>recision). This code basically just
162creates and returns a <tt>ConstantFP</tt>. Note that in the LLVM IR
Chris Lattner2e902042007-10-22 07:01:42 +0000163that constants are all uniqued together and shared. For this reason, the API
Chris Lattnerd3f0cdd2007-10-23 04:51:30 +0000164uses "the foo::get(..)" idiom instead of "new foo(..)" or "foo::create(..).</p>
Chris Lattner2e902042007-10-22 07:01:42 +0000165
166<div class="doc_code">
167<pre>
168Value *VariableExprAST::Codegen() {
169 // Look this variable up in the function.
170 Value *V = NamedValues[Name];
171 return V ? V : ErrorV("Unknown variable name");
172}
173</pre>
174</div>
175
Chris Lattnerd3f0cdd2007-10-23 04:51:30 +0000176<p>References to variables is also quite simple here. In the simple version
177of Kaleidoscope, we assume that the variable has already been emited somewhere
178and its value is available. In practice, the only values that can be in the
179<tt>NamedValues</tt> map are function arguments. This
Chris Lattner2e902042007-10-22 07:01:42 +0000180code simply checks to see that the specified name is in the map (if not, an
181unknown variable is being referenced) and returns the value for it.</p>
182
183<div class="doc_code">
184<pre>
185Value *BinaryExprAST::Codegen() {
186 Value *L = LHS-&gt;Codegen();
187 Value *R = RHS-&gt;Codegen();
188 if (L == 0 || R == 0) return 0;
189
190 switch (Op) {
191 case '+': return Builder.CreateAdd(L, R, "addtmp");
192 case '-': return Builder.CreateSub(L, R, "subtmp");
193 case '*': return Builder.CreateMul(L, R, "multmp");
194 case '&lt;':
Chris Lattner71155212007-11-06 01:39:12 +0000195 L = Builder.CreateFCmpULT(L, R, "cmptmp");
Chris Lattner2e902042007-10-22 07:01:42 +0000196 // Convert bool 0/1 to double 0.0 or 1.0
197 return Builder.CreateUIToFP(L, Type::DoubleTy, "booltmp");
198 default: return ErrorV("invalid binary operator");
199 }
200}
201</pre>
202</div>
203
Chris Lattnerd3f0cdd2007-10-23 04:51:30 +0000204<p>Binary operators start to get more interesting. The basic idea here is that
205we recursively emit code for the left-hand side of the expression, then the
206right-hand side, then we compute the result of the binary expression. In this
207code, we do a simple switch on the opcode to create the right LLVM instruction.
208</p>
Chris Lattner2e902042007-10-22 07:01:42 +0000209
Chris Lattnerd3f0cdd2007-10-23 04:51:30 +0000210<p>In this example, the LLVM builder class is starting to show its value.
211Because it knows where to insert the newly created instruction, you just have to
212specificy what instruction to create (e.g. with <tt>CreateAdd</tt>), which
213operands to use (<tt>L</tt> and <tt>R</tt> here) and optionally provide a name
214for the generated instruction. One nice thing about LLVM is that the name is
215just a hint: if there are multiple additions in a single function, the first
216will be named "addtmp" and the second will be "autorenamed" by adding a suffix,
217giving it a name like "addtmp42". Local value names for instructions are purely
218optional, but it makes it much easier to read the IR dumps.</p>
219
220<p><a href="../LangRef.html#instref">LLVM instructions</a> are constrained to
221have very strict type properties: for example, the Left and Right operators of
222an <a href="../LangRef.html#i_add">add instruction</a> have to have the same
223type, and that the result of the add matches the operands. Because all values
224in Kaleidoscope are doubles, this makes for very simple code for add, sub and
225mul.</p>
226
227<p>On the other hand, LLVM specifies that the <a
228href="../LangRef.html#i_fcmp">fcmp instruction</a> always returns an 'i1' value
229(a one bit integer). However, Kaleidoscope wants the value to be a 0.0 or 1.0
230value. In order to get these semantics, we combine the fcmp instruction with
231a <a href="../LangRef.html#i_uitofp">uitofp instruction</a>. This instruction
232converts its input integer into a floating point value by treating the input
233as an unsigned value. In contrast, if we used the <a
234href="../LangRef.html#i_sitofp">sitofp instruction</a>, the Kaleidoscope '<'
235operator would return 0.0 and -1.0, depending on the input value.</p>
Chris Lattner2e902042007-10-22 07:01:42 +0000236
237<div class="doc_code">
238<pre>
239Value *CallExprAST::Codegen() {
240 // Look up the name in the global module table.
241 Function *CalleeF = TheModule-&gt;getFunction(Callee);
242 if (CalleeF == 0)
243 return ErrorV("Unknown function referenced");
244
245 // If argument mismatch error.
246 if (CalleeF-&gt;arg_size() != Args.size())
247 return ErrorV("Incorrect # arguments passed");
248
249 std::vector&lt;Value*&gt; ArgsV;
250 for (unsigned i = 0, e = Args.size(); i != e; ++i) {
251 ArgsV.push_back(Args[i]-&gt;Codegen());
252 if (ArgsV.back() == 0) return 0;
253 }
254
255 return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp");
256}
257</pre>
258</div>
259
Chris Lattnerd3f0cdd2007-10-23 04:51:30 +0000260<p>Code generation for function calls is quite straight-forward with LLVM. The
261code above first looks the name of the function up in the LLVM Module's symbol
262table. Recall that the LLVM Module is the container that holds all of the
263functions we are JIT'ing. By giving each function the same name as what the
264user specifies, we can use the LLVM symbol table to resolve function names for
265us.</p>
266
267<p>Once we have the function to call, we recursively codegen each argument that
268is to be passed in, and create an LLVM <a href="../LangRef.html#i_call">call
269instruction</a>. Note that LLVM uses the native C calling conventions by
270default, allowing these calls to call into standard library functions like
271"sin" and "cos" with no additional effort.</p>
272
273<p>This wraps up our handling of the four basic expressions that we have so far
274in Kaleidoscope. Feel free to go in and add some more. For example, by
275browsing the <a href="../LangRef.html">LLVM language reference</a> you'll find
276several other interesting instructions that are really easy to plug into our
277basic framework.</p>
Chris Lattner2e902042007-10-22 07:01:42 +0000278
279</div>
280
281<!-- *********************************************************************** -->
Chris Lattner35abbf52007-10-23 06:23:57 +0000282<div class="doc_section"><a name="funcs">Function Code Generation</a></div>
Chris Lattner2e902042007-10-22 07:01:42 +0000283<!-- *********************************************************************** -->
284
285<div class="doc_text">
286
Chris Lattner35abbf52007-10-23 06:23:57 +0000287<p>Code generation for prototypes and functions has to handle a number of
288details, which make their code less beautiful and elegant than expression code
289generation, but they illustrate some important points. First, lets talk about
290code generation for prototypes: this is used both for function bodies as well
291as external function declarations. The code starts with:</p>
292
293<div class="doc_code">
294<pre>
295Function *PrototypeAST::Codegen() {
296 // Make the function type: double(double,double) etc.
297 std::vector&lt;const Type*&gt; Doubles(Args.size(), Type::DoubleTy);
298 FunctionType *FT = FunctionType::get(Type::DoubleTy, Doubles, false);
299
300 Function *F = new Function(FT, Function::ExternalLinkage, Name, TheModule);
301</pre>
302</div>
303
Chris Lattnercf9893d2007-11-05 19:22:50 +0000304<p>This code packs a lot of power into a few lines. Note first that this
305function returns a Function* instead of a Value*. Because a "prototype" really
306talks about the external interface for a function (not the value computed by
307an expression), it makes sense for it to return the LLVM Function it corresponds
308to when codegen'd.</p>
309
310<p>The next step is to create
Chris Lattner35abbf52007-10-23 06:23:57 +0000311the <tt>FunctionType</tt> that should be used for a given Prototype. Since all
312function arguments in Kaleidoscope are of type double, the first line creates
313a vector of "N" LLVM Double types. It then uses the <tt>FunctionType::get</tt>
314method to create a function type that takes "N" doubles as arguments, returns
315one double as a result, and that is not vararg (the false parameter indicates
316this). Note that Types in LLVM are uniqued just like Constants are, so you
317don't "new" a type, you "get" it.</p>
318
319<p>The final line above actually creates the function that the prototype will
320correspond to. This indicates which type, linkage, and name to use, and which
321module to insert into. "<a href="LangRef.html#linkage">external linkage</a>"
322means that the function may be defined outside the current module and/or that it
323is callable by functions outside the module. The Name passed in is the name the
324user specified: since "<tt>TheModule</tt>" is specified, this name is registered
325in "<tt>TheModule</tt>"s symbol table, which is used by the function call code
326above.</p>
327
328<div class="doc_code">
329<pre>
330 // If F conflicted, there was already something named 'Name'. If it has a
331 // body, don't allow redefinition or reextern.
332 if (F-&gt;getName() != Name) {
333 // Delete the one we just made and get the existing one.
334 F-&gt;eraseFromParent();
335 F = TheModule-&gt;getFunction(Name);
336</pre>
337</div>
338
339<p>The Module symbol table works just like the Function symbol table when it
340comes to name conflicts: if a new function is created with a name was previously
341added to the symbol table, it will get implicitly renamed when added to the
342Module. The code above exploits this fact to tell if there was a previous
343definition of this function.</p>
344
345<p>In Kaleidoscope, I choose to allow redefinitions of functions in two cases:
346first, we want to allow 'extern'ing a function more than once, so long as the
347prototypes for the externs match (since all arguments have the same type, we
348just have to check that the number of arguments match). Second, we want to
349allow 'extern'ing a function and then definining a body for it. This is useful
350when defining mutually recursive functions.</p>
351
352<p>In order to implement this, the code above first checks to see if there is
353a collision on the name of the function. If so, it deletes the function we just
354created (by calling <tt>eraseFromParent</tt>) and then calling
355<tt>getFunction</tt> to get the existing function with the specified name. Note
356that many APIs in LLVM have "erase" forms and "remove" forms. The "remove" form
357unlinks the object from its parent (e.g. a Function from a Module) and returns
358it. The "erase" form unlinks the object and then deletes it.</p>
359
360<div class="doc_code">
361<pre>
362 // If F already has a body, reject this.
363 if (!F-&gt;empty()) {
364 ErrorF("redefinition of function");
365 return 0;
366 }
367
368 // If F took a different number of args, reject.
369 if (F-&gt;arg_size() != Args.size()) {
370 ErrorF("redefinition of function with different # args");
371 return 0;
372 }
373 }
374</pre>
375</div>
376
377<p>In order to verify the logic above, we first check to see if the preexisting
378function is "empty". In this case, empty means that it has no basic blocks in
379it, which means it has no body. If it has no body, this means its a forward
380declaration. Since we don't allow anything after a full definition of the
381function, the code rejects this case. If the previous reference to a function
382was an 'extern', we simply verify that the number of arguments for that
383definition and this one match up. If not, we emit an error.</p>
384
385<div class="doc_code">
386<pre>
387 // Set names for all arguments.
388 unsigned Idx = 0;
389 for (Function::arg_iterator AI = F-&gt;arg_begin(); Idx != Args.size();
390 ++AI, ++Idx) {
391 AI-&gt;setName(Args[Idx]);
392
393 // Add arguments to variable symbol table.
394 NamedValues[Args[Idx]] = AI;
395 }
396 return F;
397}
398</pre>
399</div>
400
401<p>The last bit of code for prototypes loops over all of the arguments in the
402function, setting the name of the LLVM Argument objects to match and registering
403the arguments in the <tt>NamedValues</tt> map for future use by the
404<tt>VariableExprAST</tt> AST node. Once this is set up, it returns the Function
405object to the caller. Note that we don't check for conflicting
406argument names here (e.g. "extern foo(a b a)"). Doing so would be very
407straight-forward.</p>
408
409<div class="doc_code">
410<pre>
411Function *FunctionAST::Codegen() {
412 NamedValues.clear();
413
414 Function *TheFunction = Proto-&gt;Codegen();
415 if (TheFunction == 0)
416 return 0;
417</pre>
418</div>
419
420<p>Code generation for function definitions starts out simply enough: first we
Chris Lattnera1cd2242007-11-06 05:07:30 +0000421codegen the prototype (Proto) and verify that it is ok. We also clear out the
Chris Lattner35abbf52007-10-23 06:23:57 +0000422<tt>NamedValues</tt> map to make sure that there isn't anything in it from the
Chris Lattnera1cd2242007-11-06 05:07:30 +0000423last function we compiled. Code generation of the prototype ensures that there
424is an LLVM Function object that is ready to go for us.</p>
Chris Lattner35abbf52007-10-23 06:23:57 +0000425
426<div class="doc_code">
427<pre>
428 // Create a new basic block to start insertion into.
429 BasicBlock *BB = new BasicBlock("entry", TheFunction);
430 Builder.SetInsertPoint(BB);
431
432 if (Value *RetVal = Body-&gt;Codegen()) {
Chris Lattner35abbf52007-10-23 06:23:57 +0000433</pre>
434</div>
435
436<p>Now we get to the point where the <tt>Builder</tt> is set up. The first
437line creates a new <a href="http://en.wikipedia.org/wiki/Basic_block">basic
438block</a> (named "entry"), which is inserted into <tt>TheFunction</tt>. The
439second line then tells the builder that new instructions should be inserted into
440the end of the new basic block. Basic blocks in LLVM are an important part
441of functions that define the <a
442href="http://en.wikipedia.org/wiki/Control_flow_graph">Control Flow Graph</a>.
443Since we don't have any control flow, our functions will only contain one
444block so far. We'll fix this in a future installment :).</p>
445
Chris Lattnerd9b86162007-10-25 04:30:35 +0000446<div class="doc_code">
447<pre>
448 if (Value *RetVal = Body-&gt;Codegen()) {
449 // Finish off the function.
450 Builder.CreateRet(RetVal);
451
452 // Validate the generated code, checking for consistency.
453 verifyFunction(*TheFunction);
454 return TheFunction;
455 }
456</pre>
457</div>
458
Chris Lattner35abbf52007-10-23 06:23:57 +0000459<p>Once the insertion point is set up, we call the <tt>CodeGen()</tt> method for
460the root expression of the function. If no error happens, this emits code to
461compute the expression into the entry block and returns the value that was
462computed. Assuming no error, we then create an LLVM <a
Chris Lattnerd9b86162007-10-25 04:30:35 +0000463href="../LangRef.html#i_ret">ret instruction</a>, which completes the function.
464Once the function is built, we call the <tt>verifyFunction</tt> function, which
465is provided by LLVM. This function does a variety of consistency checks on the
466generated code, to determine if our compiler is doing everything right. Using
467this is important: it can catch a lot of bugs. Once the function is finished
468and validated, we return it.</p>
Chris Lattner35abbf52007-10-23 06:23:57 +0000469
470<div class="doc_code">
471<pre>
472 // Error reading body, remove function.
473 TheFunction-&gt;eraseFromParent();
474 return 0;
475}
476</pre>
477</div>
478
479<p>The only piece left here is handling of the error case. For simplicity, we
480simply handle this by deleting the function we produced with the
481<tt>eraseFromParent</tt> method. This allows the user to redefine a function
482that they incorrectly typed in before: if we didn't delete it, it would live in
483the symbol table, with a body, preventing future redefinition.</p>
484
485<p>This code does have a bug though. Since the <tt>PrototypeAST::Codegen</tt>
486can return a previously defined forward declaration, this can actually delete
487a forward declaration. There are a number of ways to fix this bug, see what you
488can come up with! Here is a testcase:</p>
489
490<div class="doc_code">
491<pre>
492extern foo(a b); # ok, defines foo.
493def foo(a b) c; # error, 'c' is invalid.
494def bar() foo(1, 2); # error, unknown function "foo"
495</pre>
496</div>
497
498</div>
499
500<!-- *********************************************************************** -->
501<div class="doc_section"><a name="driver">Driver Changes and
502Closing Thoughts</a></div>
503<!-- *********************************************************************** -->
504
505<div class="doc_text">
506
507<p>
508For now, code generation to LLVM doesn't really get us much, except that we can
509look at the pretty IR calls. The sample code inserts calls to Codegen into the
510"<tt>HandleDefinition</tt>", "<tt>HandleExtern</tt>" etc functions, and then
511dumps out the LLVM IR. This gives a nice way to look at the LLVM IR for simple
512functions. For example:
513</p>
514
515<div class="doc_code">
516<pre>
517ready> <b>4+5</b>;
518ready> Read top-level expression:
519define double @""() {
520entry:
521 %addtmp = add double 4.000000e+00, 5.000000e+00
522 ret double %addtmp
523}
524</pre>
525</div>
526
527<p>Note how the parser turns the top-level expression into anonymous functions
528for us. This will be handy when we add JIT support in the next chapter. Also
529note that the code is very literally transcribed, no optimizations are being
530performed. We will add optimizations explicitly in the next chapter.</p>
531
532<div class="doc_code">
533<pre>
534ready&gt; <b>def foo(a b) a*a + 2*a*b + b*b;</b>
535ready&gt; Read function definition:
536define double @foo(double %a, double %b) {
537entry:
538 %multmp = mul double %a, %a
539 %multmp1 = mul double 2.000000e+00, %a
540 %multmp2 = mul double %multmp1, %b
541 %addtmp = add double %multmp, %multmp2
542 %multmp3 = mul double %b, %b
543 %addtmp4 = add double %addtmp, %multmp3
544 ret double %addtmp4
545}
546</pre>
547</div>
548
549<p>This shows some simple arithmetic. Notice the striking similarity to the
550LLVM builder calls that we use to create the instructions.</p>
551
552<div class="doc_code">
553<pre>
554ready&gt; <b>def bar(a) foo(a, 4.0) + bar(31337);</b>
555ready&gt; Read function definition:
556define double @bar(double %a) {
557entry:
558 %calltmp = call double @foo( double %a, double 4.000000e+00 )
559 %calltmp1 = call double @bar( double 3.133700e+04 )
560 %addtmp = add double %calltmp, %calltmp1
561 ret double %addtmp
562}
563</pre>
564</div>
565
Chris Lattnerfc60ab02007-11-05 17:39:26 +0000566<p>This shows some function calls. Note that this function will take a long
567time to execute if you call it. In the future we'll add conditional control
568flow to make recursion actually be useful :).</p>
Chris Lattner35abbf52007-10-23 06:23:57 +0000569
570<div class="doc_code">
571<pre>
572ready&gt; <b>extern cos(x);</b>
573ready&gt; Read extern:
574declare double @cos(double)
575
576ready&gt; <b>cos(1.234);</b>
577ready&gt; Read top-level expression:
578define double @""() {
579entry:
Chris Lattner8eef4b22007-10-23 06:30:50 +0000580 %calltmp = call double @cos( double 1.234000e+00 )
Chris Lattner35abbf52007-10-23 06:23:57 +0000581 ret double %calltmp
582}
583</pre>
584</div>
585
586<p>This shows an extern for the libm "cos" function, and a call to it.</p>
587
588
589<div class="doc_code">
590<pre>
591ready&gt; <b>^D</b>
592; ModuleID = 'my cool jit'
593
594define double @""() {
595entry:
596 %addtmp = add double 4.000000e+00, 5.000000e+00
597 ret double %addtmp
598}
599
600define double @foo(double %a, double %b) {
601entry:
602 %multmp = mul double %a, %a
603 %multmp1 = mul double 2.000000e+00, %a
604 %multmp2 = mul double %multmp1, %b
605 %addtmp = add double %multmp, %multmp2
606 %multmp3 = mul double %b, %b
607 %addtmp4 = add double %addtmp, %multmp3
608 ret double %addtmp4
609}
610
611define double @bar(double %a) {
612entry:
613 %calltmp = call double @foo( double %a, double 4.000000e+00 )
614 %calltmp1 = call double @bar( double 3.133700e+04 )
615 %addtmp = add double %calltmp, %calltmp1
616 ret double %addtmp
617}
618
619declare double @cos(double)
620
621define double @""() {
622entry:
623 %calltmp = call double @cos( double 1.234000e+00 )
624 ret double %calltmp
625}
626</pre>
627</div>
628
629<p>When you quit the current demo, it dumps out the IR for the entire module
630generated. Here you can see the big picture with all the functions referencing
631each other.</p>
632
633<p>This wraps up this chapter of the Kaleidoscope tutorial. Up next we'll
634describe how to <a href="LangImpl4.html">add JIT codegen and optimizer
635support</a> to this so we can actually start running code!</p>
636
637</div>
638
639
640<!-- *********************************************************************** -->
641<div class="doc_section"><a name="code">Full Code Listing</a></div>
642<!-- *********************************************************************** -->
643
644<div class="doc_text">
645
646<p>
647Here is the complete code listing for our running example, enhanced with the
648LLVM code generator. Because this uses the LLVM libraries, we need to link
649them in. To do this, we use the <a
650href="http://llvm.org/cmds/llvm-config.html">llvm-config</a> tool to inform
651our makefile/command line about which options to use:</p>
652
653<div class="doc_code">
654<pre>
655 # Compile
Chris Lattner9ac0ca02007-10-24 05:09:48 +0000656 g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core` -o toy
Chris Lattner35abbf52007-10-23 06:23:57 +0000657 # Run
658 ./toy
659</pre>
660</div>
661
662<p>Here is the code:</p>
663
Chris Lattner2e902042007-10-22 07:01:42 +0000664<div class="doc_code">
665<pre>
666// To build this:
Chris Lattner2e902042007-10-22 07:01:42 +0000667// See example below.
668
669#include "llvm/DerivedTypes.h"
670#include "llvm/Module.h"
Chris Lattnerd9b86162007-10-25 04:30:35 +0000671#include "llvm/Analysis/Verifier.h"
Chris Lattner2e902042007-10-22 07:01:42 +0000672#include "llvm/Support/LLVMBuilder.h"
673#include &lt;cstdio&gt;
674#include &lt;string&gt;
675#include &lt;map&gt;
676#include &lt;vector&gt;
677using namespace llvm;
678
679//===----------------------------------------------------------------------===//
680// Lexer
681//===----------------------------------------------------------------------===//
682
683// The lexer returns tokens [0-255] if it is an unknown character, otherwise one
684// of these for known things.
685enum Token {
686 tok_eof = -1,
687
688 // commands
689 tok_def = -2, tok_extern = -3,
690
691 // primary
692 tok_identifier = -4, tok_number = -5,
693};
694
695static std::string IdentifierStr; // Filled in if tok_identifier
696static double NumVal; // Filled in if tok_number
697
698/// gettok - Return the next token from standard input.
699static int gettok() {
700 static int LastChar = ' ';
701
702 // Skip any whitespace.
703 while (isspace(LastChar))
704 LastChar = getchar();
705
706 if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
707 IdentifierStr = LastChar;
708 while (isalnum((LastChar = getchar())))
709 IdentifierStr += LastChar;
710
711 if (IdentifierStr == "def") return tok_def;
712 if (IdentifierStr == "extern") return tok_extern;
713 return tok_identifier;
714 }
715
716 if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+
717 std::string NumStr;
718 do {
719 NumStr += LastChar;
720 LastChar = getchar();
721 } while (isdigit(LastChar) || LastChar == '.');
722
723 NumVal = strtod(NumStr.c_str(), 0);
724 return tok_number;
725 }
726
727 if (LastChar == '#') {
728 // Comment until end of line.
729 do LastChar = getchar();
730 while (LastChar != EOF &amp;&amp; LastChar != '\n' &amp; LastChar != '\r');
731
732 if (LastChar != EOF)
733 return gettok();
734 }
735
736 // Check for end of file. Don't eat the EOF.
737 if (LastChar == EOF)
738 return tok_eof;
739
740 // Otherwise, just return the character as its ascii value.
741 int ThisChar = LastChar;
742 LastChar = getchar();
743 return ThisChar;
744}
745
746//===----------------------------------------------------------------------===//
747// Abstract Syntax Tree (aka Parse Tree)
748//===----------------------------------------------------------------------===//
749
750/// ExprAST - Base class for all expression nodes.
751class ExprAST {
752public:
753 virtual ~ExprAST() {}
754 virtual Value *Codegen() = 0;
755};
756
757/// NumberExprAST - Expression class for numeric literals like "1.0".
758class NumberExprAST : public ExprAST {
759 double Val;
760public:
Chris Lattner28571ed2007-10-23 04:27:44 +0000761 explicit NumberExprAST(double val) : Val(val) {}
Chris Lattner2e902042007-10-22 07:01:42 +0000762 virtual Value *Codegen();
763};
764
765/// VariableExprAST - Expression class for referencing a variable, like "a".
766class VariableExprAST : public ExprAST {
767 std::string Name;
768public:
Chris Lattner28571ed2007-10-23 04:27:44 +0000769 explicit VariableExprAST(const std::string &amp;name) : Name(name) {}
Chris Lattner2e902042007-10-22 07:01:42 +0000770 virtual Value *Codegen();
771};
772
773/// BinaryExprAST - Expression class for a binary operator.
774class BinaryExprAST : public ExprAST {
775 char Op;
776 ExprAST *LHS, *RHS;
777public:
778 BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs)
779 : Op(op), LHS(lhs), RHS(rhs) {}
780 virtual Value *Codegen();
781};
782
783/// CallExprAST - Expression class for function calls.
784class CallExprAST : public ExprAST {
785 std::string Callee;
786 std::vector&lt;ExprAST*&gt; Args;
787public:
788 CallExprAST(const std::string &amp;callee, std::vector&lt;ExprAST*&gt; &amp;args)
789 : Callee(callee), Args(args) {}
790 virtual Value *Codegen();
791};
792
793/// PrototypeAST - This class represents the "prototype" for a function,
794/// which captures its argument names as well as if it is an operator.
795class PrototypeAST {
796 std::string Name;
797 std::vector&lt;std::string&gt; Args;
798public:
799 PrototypeAST(const std::string &amp;name, const std::vector&lt;std::string&gt; &amp;args)
800 : Name(name), Args(args) {}
801
802 Function *Codegen();
803};
804
805/// FunctionAST - This class represents a function definition itself.
806class FunctionAST {
807 PrototypeAST *Proto;
808 ExprAST *Body;
809public:
810 FunctionAST(PrototypeAST *proto, ExprAST *body)
811 : Proto(proto), Body(body) {}
812
813 Function *Codegen();
814};
815
816//===----------------------------------------------------------------------===//
817// Parser
818//===----------------------------------------------------------------------===//
819
820/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current
821/// token the parser it looking at. getNextToken reads another token from the
822/// lexer and updates CurTok with its results.
823static int CurTok;
824static int getNextToken() {
825 return CurTok = gettok();
826}
827
828/// BinopPrecedence - This holds the precedence for each binary operator that is
829/// defined.
830static std::map&lt;char, int&gt; BinopPrecedence;
831
832/// GetTokPrecedence - Get the precedence of the pending binary operator token.
833static int GetTokPrecedence() {
834 if (!isascii(CurTok))
835 return -1;
836
837 // Make sure it's a declared binop.
838 int TokPrec = BinopPrecedence[CurTok];
839 if (TokPrec &lt;= 0) return -1;
840 return TokPrec;
841}
842
843/// Error* - These are little helper functions for error handling.
844ExprAST *Error(const char *Str) { fprintf(stderr, "Error: %s\n", Str);return 0;}
845PrototypeAST *ErrorP(const char *Str) { Error(Str); return 0; }
846FunctionAST *ErrorF(const char *Str) { Error(Str); return 0; }
847
848static ExprAST *ParseExpression();
849
850/// identifierexpr
Chris Lattner20a0c802007-11-05 17:54:34 +0000851/// ::= identifier
852/// ::= identifier '(' expression* ')'
Chris Lattner2e902042007-10-22 07:01:42 +0000853static ExprAST *ParseIdentifierExpr() {
854 std::string IdName = IdentifierStr;
855
Chris Lattner20a0c802007-11-05 17:54:34 +0000856 getNextToken(); // eat identifier.
Chris Lattner2e902042007-10-22 07:01:42 +0000857
858 if (CurTok != '(') // Simple variable ref.
859 return new VariableExprAST(IdName);
860
861 // Call.
862 getNextToken(); // eat (
863 std::vector&lt;ExprAST*&gt; Args;
Chris Lattner71155212007-11-06 01:39:12 +0000864 if (CurTok != ')') {
865 while (1) {
866 ExprAST *Arg = ParseExpression();
867 if (!Arg) return 0;
868 Args.push_back(Arg);
Chris Lattner2e902042007-10-22 07:01:42 +0000869
Chris Lattner71155212007-11-06 01:39:12 +0000870 if (CurTok == ')') break;
Chris Lattner2e902042007-10-22 07:01:42 +0000871
Chris Lattner71155212007-11-06 01:39:12 +0000872 if (CurTok != ',')
873 return Error("Expected ')'");
874 getNextToken();
875 }
Chris Lattner2e902042007-10-22 07:01:42 +0000876 }
877
878 // Eat the ')'.
879 getNextToken();
880
881 return new CallExprAST(IdName, Args);
882}
883
884/// numberexpr ::= number
885static ExprAST *ParseNumberExpr() {
886 ExprAST *Result = new NumberExprAST(NumVal);
887 getNextToken(); // consume the number
888 return Result;
889}
890
891/// parenexpr ::= '(' expression ')'
892static ExprAST *ParseParenExpr() {
893 getNextToken(); // eat (.
894 ExprAST *V = ParseExpression();
895 if (!V) return 0;
896
897 if (CurTok != ')')
898 return Error("expected ')'");
899 getNextToken(); // eat ).
900 return V;
901}
902
903/// primary
904/// ::= identifierexpr
905/// ::= numberexpr
906/// ::= parenexpr
907static ExprAST *ParsePrimary() {
908 switch (CurTok) {
909 default: return Error("unknown token when expecting an expression");
910 case tok_identifier: return ParseIdentifierExpr();
911 case tok_number: return ParseNumberExpr();
912 case '(': return ParseParenExpr();
913 }
914}
915
916/// binoprhs
917/// ::= ('+' primary)*
918static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
919 // If this is a binop, find its precedence.
920 while (1) {
921 int TokPrec = GetTokPrecedence();
922
923 // If this is a binop that binds at least as tightly as the current binop,
924 // consume it, otherwise we are done.
925 if (TokPrec &lt; ExprPrec)
926 return LHS;
927
928 // Okay, we know this is a binop.
929 int BinOp = CurTok;
930 getNextToken(); // eat binop
931
932 // Parse the primary expression after the binary operator.
933 ExprAST *RHS = ParsePrimary();
934 if (!RHS) return 0;
935
936 // If BinOp binds less tightly with RHS than the operator after RHS, let
937 // the pending operator take RHS as its LHS.
938 int NextPrec = GetTokPrecedence();
939 if (TokPrec &lt; NextPrec) {
940 RHS = ParseBinOpRHS(TokPrec+1, RHS);
941 if (RHS == 0) return 0;
942 }
943
944 // Merge LHS/RHS.
945 LHS = new BinaryExprAST(BinOp, LHS, RHS);
946 }
947}
948
949/// expression
950/// ::= primary binoprhs
951///
952static ExprAST *ParseExpression() {
953 ExprAST *LHS = ParsePrimary();
954 if (!LHS) return 0;
955
956 return ParseBinOpRHS(0, LHS);
957}
958
959/// prototype
960/// ::= id '(' id* ')'
961static PrototypeAST *ParsePrototype() {
962 if (CurTok != tok_identifier)
963 return ErrorP("Expected function name in prototype");
964
965 std::string FnName = IdentifierStr;
966 getNextToken();
967
968 if (CurTok != '(')
969 return ErrorP("Expected '(' in prototype");
970
971 std::vector&lt;std::string&gt; ArgNames;
972 while (getNextToken() == tok_identifier)
973 ArgNames.push_back(IdentifierStr);
974 if (CurTok != ')')
975 return ErrorP("Expected ')' in prototype");
976
977 // success.
978 getNextToken(); // eat ')'.
979
980 return new PrototypeAST(FnName, ArgNames);
981}
982
983/// definition ::= 'def' prototype expression
984static FunctionAST *ParseDefinition() {
985 getNextToken(); // eat def.
986 PrototypeAST *Proto = ParsePrototype();
987 if (Proto == 0) return 0;
988
989 if (ExprAST *E = ParseExpression())
990 return new FunctionAST(Proto, E);
991 return 0;
992}
993
994/// toplevelexpr ::= expression
995static FunctionAST *ParseTopLevelExpr() {
996 if (ExprAST *E = ParseExpression()) {
997 // Make an anonymous proto.
998 PrototypeAST *Proto = new PrototypeAST("", std::vector&lt;std::string&gt;());
999 return new FunctionAST(Proto, E);
1000 }
1001 return 0;
1002}
1003
1004/// external ::= 'extern' prototype
1005static PrototypeAST *ParseExtern() {
1006 getNextToken(); // eat extern.
1007 return ParsePrototype();
1008}
1009
1010//===----------------------------------------------------------------------===//
1011// Code Generation
1012//===----------------------------------------------------------------------===//
1013
1014static Module *TheModule;
1015static LLVMBuilder Builder;
1016static std::map&lt;std::string, Value*&gt; NamedValues;
1017
1018Value *ErrorV(const char *Str) { Error(Str); return 0; }
1019
1020Value *NumberExprAST::Codegen() {
1021 return ConstantFP::get(Type::DoubleTy, APFloat(Val));
1022}
1023
1024Value *VariableExprAST::Codegen() {
1025 // Look this variable up in the function.
1026 Value *V = NamedValues[Name];
1027 return V ? V : ErrorV("Unknown variable name");
1028}
1029
1030Value *BinaryExprAST::Codegen() {
1031 Value *L = LHS-&gt;Codegen();
1032 Value *R = RHS-&gt;Codegen();
1033 if (L == 0 || R == 0) return 0;
1034
1035 switch (Op) {
1036 case '+': return Builder.CreateAdd(L, R, "addtmp");
1037 case '-': return Builder.CreateSub(L, R, "subtmp");
1038 case '*': return Builder.CreateMul(L, R, "multmp");
1039 case '&lt;':
Chris Lattner71155212007-11-06 01:39:12 +00001040 L = Builder.CreateFCmpULT(L, R, "cmptmp");
Chris Lattner2e902042007-10-22 07:01:42 +00001041 // Convert bool 0/1 to double 0.0 or 1.0
1042 return Builder.CreateUIToFP(L, Type::DoubleTy, "booltmp");
1043 default: return ErrorV("invalid binary operator");
1044 }
1045}
1046
1047Value *CallExprAST::Codegen() {
1048 // Look up the name in the global module table.
1049 Function *CalleeF = TheModule-&gt;getFunction(Callee);
1050 if (CalleeF == 0)
1051 return ErrorV("Unknown function referenced");
1052
1053 // If argument mismatch error.
1054 if (CalleeF-&gt;arg_size() != Args.size())
1055 return ErrorV("Incorrect # arguments passed");
1056
1057 std::vector&lt;Value*&gt; ArgsV;
1058 for (unsigned i = 0, e = Args.size(); i != e; ++i) {
1059 ArgsV.push_back(Args[i]-&gt;Codegen());
1060 if (ArgsV.back() == 0) return 0;
1061 }
1062
1063 return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp");
1064}
1065
1066Function *PrototypeAST::Codegen() {
1067 // Make the function type: double(double,double) etc.
Chris Lattner35abbf52007-10-23 06:23:57 +00001068 std::vector&lt;const Type*&gt; Doubles(Args.size(), Type::DoubleTy);
1069 FunctionType *FT = FunctionType::get(Type::DoubleTy, Doubles, false);
Chris Lattner2e902042007-10-22 07:01:42 +00001070
1071 Function *F = new Function(FT, Function::ExternalLinkage, Name, TheModule);
1072
1073 // If F conflicted, there was already something named 'Name'. If it has a
1074 // body, don't allow redefinition or reextern.
1075 if (F-&gt;getName() != Name) {
1076 // Delete the one we just made and get the existing one.
1077 F-&gt;eraseFromParent();
1078 F = TheModule-&gt;getFunction(Name);
1079
1080 // If F already has a body, reject this.
1081 if (!F-&gt;empty()) {
1082 ErrorF("redefinition of function");
1083 return 0;
1084 }
1085
1086 // If F took a different number of args, reject.
1087 if (F-&gt;arg_size() != Args.size()) {
1088 ErrorF("redefinition of function with different # args");
1089 return 0;
1090 }
1091 }
1092
1093 // Set names for all arguments.
1094 unsigned Idx = 0;
1095 for (Function::arg_iterator AI = F-&gt;arg_begin(); Idx != Args.size();
1096 ++AI, ++Idx) {
1097 AI-&gt;setName(Args[Idx]);
1098
1099 // Add arguments to variable symbol table.
1100 NamedValues[Args[Idx]] = AI;
1101 }
1102
1103 return F;
1104}
1105
1106Function *FunctionAST::Codegen() {
1107 NamedValues.clear();
1108
1109 Function *TheFunction = Proto-&gt;Codegen();
1110 if (TheFunction == 0)
1111 return 0;
1112
1113 // Create a new basic block to start insertion into.
Chris Lattner35abbf52007-10-23 06:23:57 +00001114 BasicBlock *BB = new BasicBlock("entry", TheFunction);
1115 Builder.SetInsertPoint(BB);
Chris Lattner2e902042007-10-22 07:01:42 +00001116
1117 if (Value *RetVal = Body-&gt;Codegen()) {
1118 // Finish off the function.
1119 Builder.CreateRet(RetVal);
Chris Lattnerd9b86162007-10-25 04:30:35 +00001120
1121 // Validate the generated code, checking for consistency.
1122 verifyFunction(*TheFunction);
Chris Lattner2e902042007-10-22 07:01:42 +00001123 return TheFunction;
1124 }
1125
1126 // Error reading body, remove function.
1127 TheFunction-&gt;eraseFromParent();
1128 return 0;
1129}
1130
1131//===----------------------------------------------------------------------===//
1132// Top-Level parsing and JIT Driver
1133//===----------------------------------------------------------------------===//
1134
1135static void HandleDefinition() {
1136 if (FunctionAST *F = ParseDefinition()) {
1137 if (Function *LF = F-&gt;Codegen()) {
1138 fprintf(stderr, "Read function definition:");
1139 LF-&gt;dump();
1140 }
1141 } else {
1142 // Skip token for error recovery.
1143 getNextToken();
1144 }
1145}
1146
1147static void HandleExtern() {
1148 if (PrototypeAST *P = ParseExtern()) {
1149 if (Function *F = P-&gt;Codegen()) {
1150 fprintf(stderr, "Read extern: ");
1151 F-&gt;dump();
1152 }
1153 } else {
1154 // Skip token for error recovery.
1155 getNextToken();
1156 }
1157}
1158
1159static void HandleTopLevelExpression() {
1160 // Evaluate a top level expression into an anonymous function.
1161 if (FunctionAST *F = ParseTopLevelExpr()) {
1162 if (Function *LF = F-&gt;Codegen()) {
1163 fprintf(stderr, "Read top-level expression:");
1164 LF-&gt;dump();
1165 }
1166 } else {
1167 // Skip token for error recovery.
1168 getNextToken();
1169 }
1170}
1171
1172/// top ::= definition | external | expression | ';'
1173static void MainLoop() {
1174 while (1) {
1175 fprintf(stderr, "ready&gt; ");
1176 switch (CurTok) {
1177 case tok_eof: return;
1178 case ';': getNextToken(); break; // ignore top level semicolons.
1179 case tok_def: HandleDefinition(); break;
1180 case tok_extern: HandleExtern(); break;
1181 default: HandleTopLevelExpression(); break;
1182 }
1183 }
1184}
1185
1186
1187
1188//===----------------------------------------------------------------------===//
1189// "Library" functions that can be "extern'd" from user code.
1190//===----------------------------------------------------------------------===//
1191
1192/// putchard - putchar that takes a double and returns 0.
1193extern "C"
1194double putchard(double X) {
1195 putchar((char)X);
1196 return 0;
1197}
1198
1199//===----------------------------------------------------------------------===//
1200// Main driver code.
1201//===----------------------------------------------------------------------===//
1202
1203int main() {
1204 TheModule = new Module("my cool jit");
1205
1206 // Install standard binary operators.
1207 // 1 is lowest precedence.
1208 BinopPrecedence['&lt;'] = 10;
1209 BinopPrecedence['+'] = 20;
1210 BinopPrecedence['-'] = 20;
1211 BinopPrecedence['*'] = 40; // highest.
1212
1213 // Prime the first token.
1214 fprintf(stderr, "ready&gt; ");
1215 getNextToken();
1216
1217 MainLoop();
1218 TheModule-&gt;dump();
1219 return 0;
1220}
Chris Lattner2e902042007-10-22 07:01:42 +00001221</pre>
1222</div>
1223</div>
1224
1225<!-- *********************************************************************** -->
1226<hr>
1227<address>
1228 <a href="http://jigsaw.w3.org/css-validator/check/referer"><img
1229 src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"></a>
1230 <a href="http://validator.w3.org/check/referer"><img
Chris Lattner8eef4b22007-10-23 06:30:50 +00001231 src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"></a>
Chris Lattner2e902042007-10-22 07:01:42 +00001232
1233 <a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
1234 <a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
1235 Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $
1236</address>
1237</body>
1238</html>