Various updates from Sam Bishop:

"I have been working my way through the JIT and Kaleidoscope tutorials in my
(minuscule) spare time.  Thanks again for writing them!  I have attached a
patch containing some minor changes, ranging from spelling and grammar fixes
to adding a "Next: <next tutorial section>" hyperlink to the bottom of each
page.

Every page has been given the "next link" treatment, but otherwise I'm only
half way through the Kaleidoscope tutorial.  I will send a follow-on patch
if time permits."



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@46933 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner
2008-02-10 19:11:04 +00:00
parent 916c954bf2
commit 729eb14ae8
9 changed files with 87 additions and 75 deletions
+16 -15
View File
@@ -25,7 +25,7 @@
<div class="doc_text">
<p>For starters, lets consider a relatively straightforward function that takes three integer parameters and returns an arithmetic combination of them. This is nice and simple, especially since it involves no control flow:</p>
<p>For starters, let's consider a relatively straightforward function that takes three integer parameters and returns an arithmetic combination of them. This is nice and simple, especially since it involves no control flow:</p>
<div class="doc_code">
<pre>
@@ -86,7 +86,7 @@ int main(int argc, char**argv) {
</pre>
</div>
<p>The first segment is pretty simple: it creates an LLVM “module.” In LLVM, a module represents a single unit of code that is to be processed together. A module contains things like global variables and function declarations and implementations. Here, weve declared a <code>makeLLVMModule()</code> function to do the real work of creating the module. Dont worry, well be looking at that one next!</p>
<p>The first segment is pretty simple: it creates an LLVM “module.” In LLVM, a module represents a single unit of code that is to be processed together. A module contains things like global variables, function declarations, and implementations. Here weve declared a <code>makeLLVMModule()</code> function to do the real work of creating the module. Dont worry, well be looking at that one next!</p>
<p>The second segment runs the LLVM module verifier on our newly created module. While this probably isnt really necessary for a simple module like this one, its always a good idea, especially if youre generating LLVM IR based on some input. The verifier will print an error message if your LLVM module is malformed in any way.</p>
@@ -106,7 +106,7 @@ Module* makeLLVMModule() {
<div class="doc_code">
<pre>
Constant* c = mod->getOrInsertFunction("mul_add",
Constant* c = mod-&gt;getOrInsertFunction("mul_add",
/*ret type*/ IntegerType::get(32),
/*args*/ IntegerType::get(32),
IntegerType::get(32),
@@ -114,31 +114,31 @@ Module* makeLLVMModule() {
/*varargs terminated with null*/ NULL);
Function* mul_add = cast&lt;Function&gt;(c);
mul_add->setCallingConv(CallingConv::C);
mul_add-&gt;setCallingConv(CallingConv::C);
</pre>
</div>
<p>We construct our <code>Function</code> by calling <code>getOrInsertFunction()</code> on our module, passing in the name, return type, and argument types of the function. In the case of our <code>mul_add</code> function, that means one 32-bit integer for the return value, and three 32-bit integers for the arguments.</p>
<p>We construct our <code>Function</code> by calling <code>getOrInsertFunction()</code> on our module, passing in the name, return type, and argument types of the function. In the case of our <code>mul_add</code> function, that means one 32-bit integer for the return value and three 32-bit integers for the arguments.</p>
<p>You'll notice that <code>getOrInsertFunction</code> doesn't actually return a <code>Function*</code>. This is because, if the function already existed, but with a different prototype, <code>getOrInsertFunction</code> will return a cast of the existing function to the desired prototype. Since we know that there's not already a <code>mul_add</code> function, we can safely just cast <code>c</code> to a <code>Function*</code>.
<p>You'll notice that <code>getOrInsertFunction()</code> doesn't actually return a <code>Function*</code>. This is because <code>getOrInsertFunction()</code> will return a cast of the existing function if the function already existed with a different prototype. Since we know that there's not already a <code>mul_add</code> function, we can safely just cast <code>c</code> to a <code>Function*</code>.
<p>In addition, we set the calling convention for our new function to be the C calling convention. This isnt strictly necessary, but it insures that our new function will interoperate properly with C code, which is a good thing.</p>
<div class="doc_code">
<pre>
Function::arg_iterator args = mul_add->arg_begin();
Function::arg_iterator args = mul_add-&gt;arg_begin();
Value* x = args++;
x->setName("x");
x-&gt;setName("x");
Value* y = args++;
y->setName("y");
y-&gt;setName("y");
Value* z = args++;
z->setName("z");
z-&gt;setName("z");
</pre>
</div>
<p>While were setting up our function, lets also give names to the parameters. This also isnt strictly necessary (LLVM will generate names for them if you dont specify them), but itll make looking at our output somewhat more pleasant. To name the parameters, we iterator over the arguments of our function, and call <code>setName()</code> on them. Well also keep the pointer to <code>x</code>, <code>y</code>, and <code>z</code> around, since well need them when we get around to creating instructions.</p>
<p>While were setting up our function, lets also give names to the parameters. This also isnt strictly necessary (LLVM will generate names for them if you dont specify them), but itll make looking at our output somewhat more pleasant. To name the parameters, we iterate over the arguments of our function and call <code>setName()</code> on them. Well also keep the pointer to <code>x</code>, <code>y</code>, and <code>z</code> around, since well need them when we get around to creating instructions.</p>
<p>Great! We have a function now. But what good is a function if it has no body? Before we start working on a body for our new function, we need to recall some details of the LLVM IR. The IR, being an abstract assembly language, represents control flow using jumps (we call them branches), both conditional and unconditional. The straight-line sequences of code between branches are called basic blocks, or just blocks. To create a body for our function, we fill it with blocks!</p>
<p>Great! We have a function now. But what good is a function if it has no body? Before we start working on a body for our new function, we need to recall some details of the LLVM IR. The IR, being an abstract assembly language, represents control flow using jumps (we call them branches), both conditional and unconditional. The straight-line sequences of code between branches are called basic blocks, or just blocks. To create a body for our function, we fill it with blocks:</p>
<div class="doc_code">
<pre>
@@ -165,17 +165,18 @@ Module* makeLLVMModule() {
<p>The final step in creating our function is to create the instructions that make it up. Our <code>mul_add</code> function is composed of just three instructions: a multiply, an add, and a return. <code>LLVMBuilder</code> gives us a simple interface for constructing these instructions and appending them to the “entry” block. Each of the calls to <code>LLVMBuilder</code> returns a <code>Value*</code> that represents the value yielded by the instruction. Youll also notice that, above, <code>x</code>, <code>y</code>, and <code>z</code> are also <code>Value*</code>s, so its clear that instructions operate on <code>Value*</code>s.</p>
<p>And thats it! Now you can compile and run your code, and get a wonderful textual print out of the LLVM IR we saw at the beginning. To compile, use the following commandline as a guide:</p>
<p>And thats it! Now you can compile and run your code, and get a wonderful textual print out of the LLVM IR we saw at the beginning. To compile, use the following command line as a guide:</p>
<div class="doc_code">
<pre>
# c++ -g tut2.cpp `llvm-config --cppflags --ldflags --libs core` -o tut2
# ./tut2
# c++ -g tut1.cpp `llvm-config --cppflags --ldflags --libs core` -o tut1
# ./tut1
</pre>
</div>
<p>The <code>llvm-config</code> utility is used to obtain the necessary GCC-compatible compiler flags for linking with LLVM. For this example, we only need the 'core' library. We'll use others once we start adding optimizers and the JIT engine.</p>
<a href="JITTutorial2.html">Next: A More Complicated Function</a>
</div>
<!-- *********************************************************************** -->