mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-07-02 22:30:36 +00:00
minor edits
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43807 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
60a877d713
commit
a54c2019e1
|
@ -39,8 +39,8 @@ Flow</li>
|
||||||
<div class="doc_text">
|
<div class="doc_text">
|
||||||
|
|
||||||
<p>Welcome to Chapter 4 of the "<a href="index.html">Implementing a language
|
<p>Welcome to Chapter 4 of the "<a href="index.html">Implementing a language
|
||||||
with LLVM</a>" tutorial. Parts 1-3 described the implementation of a simple
|
with LLVM</a>" tutorial. Chapters 1-3 described the implementation of a simple
|
||||||
language and included support for generating LLVM IR. This chapter describes
|
language and added support for generating LLVM IR. This chapter describes
|
||||||
two new techniques: adding optimizer support to your language, and adding JIT
|
two new techniques: adding optimizer support to your language, and adding JIT
|
||||||
compiler support. This shows how to get nice efficient code for your
|
compiler support. This shows how to get nice efficient code for your
|
||||||
language.</p>
|
language.</p>
|
||||||
|
@ -109,7 +109,7 @@ entry:
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>Well, that was easy. :) In practice, we recommend always using
|
<p>Well, that was easy :). In practice, we recommend always using
|
||||||
<tt>LLVMFoldingBuilder</tt> when generating code like this. It has no
|
<tt>LLVMFoldingBuilder</tt> when generating code like this. It has no
|
||||||
"syntactic overhead" for its use (you don't have to uglify your compiler with
|
"syntactic overhead" for its use (you don't have to uglify your compiler with
|
||||||
constant checks everywhere) and it can dramatically reduce the amount of
|
constant checks everywhere) and it can dramatically reduce the amount of
|
||||||
|
@ -166,7 +166,8 @@ at link time, this can be a substantial portion of the whole program). It also
|
||||||
supports and includes "per-function" passes which just operate on a single
|
supports and includes "per-function" passes which just operate on a single
|
||||||
function at a time, without looking at other functions. For more information
|
function at a time, without looking at other functions. For more information
|
||||||
on passes and how the get run, see the <a href="../WritingAnLLVMPass.html">How
|
on passes and how the get run, see the <a href="../WritingAnLLVMPass.html">How
|
||||||
to Write a Pass</a> document.</p>
|
to Write a Pass</a> document and the <a href="../Passes.html">List of LLVM
|
||||||
|
Passes</a>.</p>
|
||||||
|
|
||||||
<p>For Kaleidoscope, we are currently generating functions on the fly, one at
|
<p>For Kaleidoscope, we are currently generating functions on the fly, one at
|
||||||
a time, as the user types them in. We aren't shooting for the ultimate
|
a time, as the user types them in. We aren't shooting for the ultimate
|
||||||
|
@ -212,7 +213,7 @@ add a set of optimizations to run. The code looks like this:</p>
|
||||||
that we're not going to take advantage of here, so I won't dive into what it is
|
that we're not going to take advantage of here, so I won't dive into what it is
|
||||||
all about.</p>
|
all about.</p>
|
||||||
|
|
||||||
<p>The meat of the matter is the definition of the "<tt>OurFPM</tt>". It
|
<p>The meat of the matter is the definition of "<tt>OurFPM</tt>". It
|
||||||
requires a pointer to the <tt>Module</tt> (through the <tt>ModuleProvider</tt>)
|
requires a pointer to the <tt>Module</tt> (through the <tt>ModuleProvider</tt>)
|
||||||
to construct itself. Once it is set up, we use a series of "add" calls to add
|
to construct itself. Once it is set up, we use a series of "add" calls to add
|
||||||
a bunch of LLVM passes. The first pass is basically boilerplate, it adds a pass
|
a bunch of LLVM passes. The first pass is basically boilerplate, it adds a pass
|
||||||
|
@ -222,10 +223,10 @@ which we will get to in the next section.</p>
|
||||||
|
|
||||||
<p>In this case, we choose to add 4 optimization passes. The passes we chose
|
<p>In this case, we choose to add 4 optimization passes. The passes we chose
|
||||||
here are a pretty standard set of "cleanup" optimizations that are useful for
|
here are a pretty standard set of "cleanup" optimizations that are useful for
|
||||||
a wide variety of code. I won't delve into what they do, but believe that they
|
a wide variety of code. I won't delve into what they do, but believe me that
|
||||||
are a good starting place.</p>
|
they are a good starting place :).</p>
|
||||||
|
|
||||||
<p>Once the passmanager, is set up, we need to make use of it. We do this by
|
<p>Once the PassManager is set up, we need to make use of it. We do this by
|
||||||
running it after our newly created function is constructed (in
|
running it after our newly created function is constructed (in
|
||||||
<tt>FunctionAST::Codegen</tt>), but before it is returned to the client:</p>
|
<tt>FunctionAST::Codegen</tt>), but before it is returned to the client:</p>
|
||||||
|
|
||||||
|
@ -238,8 +239,8 @@ running it after our newly created function is constructed (in
|
||||||
// Validate the generated code, checking for consistency.
|
// Validate the generated code, checking for consistency.
|
||||||
verifyFunction(*TheFunction);
|
verifyFunction(*TheFunction);
|
||||||
|
|
||||||
// Optimize the function.
|
<b>// Optimize the function.
|
||||||
TheFPM->run(*TheFunction);
|
TheFPM->run(*TheFunction);</b>
|
||||||
|
|
||||||
return TheFunction;
|
return TheFunction;
|
||||||
}
|
}
|
||||||
|
@ -265,7 +266,7 @@ entry:
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>As expected, we now get our nicely optimized code, saving a floating point
|
<p>As expected, we now get our nicely optimized code, saving a floating point
|
||||||
add from the program.</p>
|
add instruction from every execution of this function.</p>
|
||||||
|
|
||||||
<p>LLVM provides a wide variety of optimizations that can be used in certain
|
<p>LLVM provides a wide variety of optimizations that can be used in certain
|
||||||
circumstances. Some <a href="../Passes.html">documentation about the various
|
circumstances. Some <a href="../Passes.html">documentation about the various
|
||||||
|
@ -286,15 +287,15 @@ executing it!</p>
|
||||||
|
|
||||||
<div class="doc_text">
|
<div class="doc_text">
|
||||||
|
|
||||||
<p>Once the code is available in LLVM IR form a wide variety of tools can be
|
<p>Code that is available in LLVM IR can have a wide variety of tools
|
||||||
applied to it. For example, you can run optimizations on it (as we did above),
|
applied to it. For example, you can run optimizations on it (as we did above),
|
||||||
you can dump it out in textual or binary forms, you can compile the code to an
|
you can dump it out in textual or binary forms, you can compile the code to an
|
||||||
assembly file (.s) for some target, or you can JIT compile it. The nice thing
|
assembly file (.s) for some target, or you can JIT compile it. The nice thing
|
||||||
about the LLVM IR representation is that it is the common currency between many
|
about the LLVM IR representation is that it is the "common currency" between
|
||||||
different parts of the compiler.
|
many different parts of the compiler.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>In this chapter, we'll add JIT compiler support to our interpreter. The
|
<p>In this section, we'll add JIT compiler support to our interpreter. The
|
||||||
basic idea that we want for Kaleidoscope is to have the user enter function
|
basic idea that we want for Kaleidoscope is to have the user enter function
|
||||||
bodies as they do now, but immediately evaluate the top-level expressions they
|
bodies as they do now, but immediately evaluate the top-level expressions they
|
||||||
type in. For example, if they type in "1 + 2;", we should evaluate and print
|
type in. For example, if they type in "1 + 2;", we should evaluate and print
|
||||||
|
@ -306,12 +307,12 @@ by adding a global variable and a call in <tt>main</tt>:</p>
|
||||||
|
|
||||||
<div class="doc_code">
|
<div class="doc_code">
|
||||||
<pre>
|
<pre>
|
||||||
static ExecutionEngine *TheExecutionEngine;
|
<b>static ExecutionEngine *TheExecutionEngine;</b>
|
||||||
...
|
...
|
||||||
int main() {
|
int main() {
|
||||||
..
|
..
|
||||||
// Create the JIT.
|
<b>// Create the JIT.
|
||||||
TheExecutionEngine = ExecutionEngine::create(TheModule);
|
TheExecutionEngine = ExecutionEngine::create(TheModule);</b>
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
@ -337,13 +338,13 @@ static void HandleTopLevelExpression() {
|
||||||
if (Function *LF = F->Codegen()) {
|
if (Function *LF = F->Codegen()) {
|
||||||
LF->dump(); // Dump the function for exposition purposes.
|
LF->dump(); // Dump the function for exposition purposes.
|
||||||
|
|
||||||
// JIT the function, returning a function pointer.
|
<b>// JIT the function, returning a function pointer.
|
||||||
void *FPtr = TheExecutionEngine->getPointerToFunction(LF);
|
void *FPtr = TheExecutionEngine->getPointerToFunction(LF);
|
||||||
|
|
||||||
// Cast it to the right type (takes no arguments, returns a double) so we
|
// Cast it to the right type (takes no arguments, returns a double) so we
|
||||||
// can call it as a native function.
|
// can call it as a native function.
|
||||||
double (*FP)() = (double (*)())FPtr;
|
double (*FP)() = (double (*)())FPtr;
|
||||||
fprintf(stderr, "Evaluated to %f\n", FP());
|
fprintf(stderr, "Evaluated to %f\n", FP());</b>
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
@ -404,9 +405,9 @@ itself</em>.</p>
|
||||||
<p>What actually happened here is that the anonymous function is
|
<p>What actually happened here is that the anonymous function is
|
||||||
JIT'd when requested. When the Kaleidoscope app calls through the function
|
JIT'd when requested. When the Kaleidoscope app calls through the function
|
||||||
pointer that is returned, the anonymous function starts executing. It ends up
|
pointer that is returned, the anonymous function starts executing. It ends up
|
||||||
making the call for the "testfunc" function, and ends up in a stub that invokes
|
making the call to the "testfunc" function, and ends up in a stub that invokes
|
||||||
the JIT, lazily, on testfunc. Once the JIT finishes lazily compiling testfunc,
|
the JIT, lazily, on testfunc. Once the JIT finishes lazily compiling testfunc,
|
||||||
it returns and the code reexecutes the call.</p>
|
it returns and the code re-executes the call.</p>
|
||||||
|
|
||||||
<p>In summary, the JIT will lazily JIT code on the fly as it is needed. The
|
<p>In summary, the JIT will lazily JIT code on the fly as it is needed. The
|
||||||
JIT provides a number of other more advanced interfaces for things like freeing
|
JIT provides a number of other more advanced interfaces for things like freeing
|
||||||
|
@ -445,11 +446,13 @@ ready> <b>foo(4.0);</b>
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>Whoa, how does the JIT know about sin and cos? The answer is simple: in this
|
<p>Whoa, how does the JIT know about sin and cos? The answer is surprisingly
|
||||||
|
simple: in this
|
||||||
example, the JIT started execution of a function and got to a function call. It
|
example, the JIT started execution of a function and got to a function call. It
|
||||||
realized that the function was not yet JIT compiled and invoked the standard set
|
realized that the function was not yet JIT compiled and invoked the standard set
|
||||||
of routines to resolve the function. In this case, there is no body defined
|
of routines to resolve the function. In this case, there is no body defined
|
||||||
for the function, so the JIT ended up calling "<tt>dlsym("sin")</tt>" on itself.
|
for the function, so the JIT ended up calling "<tt>dlsym("sin")</tt>" on the
|
||||||
|
Kaleidoscope process itself.
|
||||||
Since "<tt>sin</tt>" is defined within the JIT's address space, it simply
|
Since "<tt>sin</tt>" is defined within the JIT's address space, it simply
|
||||||
patches up calls in the module to call the libm version of <tt>sin</tt>
|
patches up calls in the module to call the libm version of <tt>sin</tt>
|
||||||
directly.</p>
|
directly.</p>
|
||||||
|
@ -479,7 +482,7 @@ double putchard(double X) {
|
||||||
|
|
||||||
<p>Now we can produce simple output to the console by using things like:
|
<p>Now we can produce simple output to the console by using things like:
|
||||||
"<tt>extern putchard(x); putchard(120);</tt>", which prints a lowercase 'x' on
|
"<tt>extern putchard(x); putchard(120);</tt>", which prints a lowercase 'x' on
|
||||||
the console (120 is the ascii code for 'x'). Similar code could be used to
|
the console (120 is the ASCII code for 'x'). Similar code could be used to
|
||||||
implement file I/O, console input, and many other capabilities in
|
implement file I/O, console input, and many other capabilities in
|
||||||
Kaleidoscope.</p>
|
Kaleidoscope.</p>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user