1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00

Update tutorial to reflect the current APIs. Also correct a small omission in

LangImpl6.html (it needed to defined the 'binary :' operator).
PR9052

llvm-svn: 142123
This commit is contained in:
Bill Wendling 2011-10-16 08:06:54 +00:00
parent 2cd868184c
commit 2e33fb0c40
6 changed files with 239 additions and 214 deletions

View File

@ -801,10 +801,10 @@ course.) To build this, just compile with:</p>
<div class="doc_code"> <div class="doc_code">
<pre> <pre>
# Compile # Compile
g++ -g -O3 toy.cpp clang++ -g -O3 toy.cpp
# Run # Run
./a.out ./a.out
</pre> </pre>
</div> </div>

View File

@ -266,7 +266,7 @@ Value *CallExprAST::Codegen() {
if (ArgsV.back() == 0) return 0; if (ArgsV.back() == 0) return 0;
} }
return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp"); return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
} }
</pre> </pre>
</div> </div>
@ -308,8 +308,8 @@ bodies and external function declarations. The code starts with:</p>
<pre> <pre>
Function *PrototypeAST::Codegen() { Function *PrototypeAST::Codegen() {
// Make the function type: double(double,double) etc. // Make the function type: double(double,double) etc.
std::vector&lt;const Type*&gt; Doubles(Args.size(), std::vector&lt;Type*&gt; Doubles(Args.size(),
Type::getDoubleTy(getGlobalContext())); Type::getDoubleTy(getGlobalContext()));
FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()), FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
Doubles, false); Doubles, false);
@ -532,9 +532,9 @@ functions. For example:
<pre> <pre>
ready> <b>4+5</b>; ready> <b>4+5</b>;
Read top-level expression: Read top-level expression:
define double @""() { define double @0() {
entry: entry:
ret double 9.000000e+00 ret double 9.000000e+00
} }
</pre> </pre>
</div> </div>
@ -553,13 +553,13 @@ ready&gt; <b>def foo(a b) a*a + 2*a*b + b*b;</b>
Read function definition: Read function definition:
define double @foo(double %a, double %b) { define double @foo(double %a, double %b) {
entry: entry:
%multmp = fmul double %a, %a %multmp = fmul double %a, %a
%multmp1 = fmul double 2.000000e+00, %a %multmp1 = fmul double 2.000000e+00, %a
%multmp2 = fmul double %multmp1, %b %multmp2 = fmul double %multmp1, %b
%addtmp = fadd double %multmp, %multmp2 %addtmp = fadd double %multmp, %multmp2
%multmp3 = fmul double %b, %b %multmp3 = fmul double %b, %b
%addtmp4 = fadd double %addtmp, %multmp3 %addtmp4 = fadd double %addtmp, %multmp3
ret double %addtmp4 ret double %addtmp4
} }
</pre> </pre>
</div> </div>
@ -573,10 +573,10 @@ ready&gt; <b>def bar(a) foo(a, 4.0) + bar(31337);</b>
Read function definition: Read function definition:
define double @bar(double %a) { define double @bar(double %a) {
entry: entry:
%calltmp = call double @foo(double %a, double 4.000000e+00) %calltmp = call double @foo(double %a, double 4.000000e+00)
%calltmp1 = call double @bar(double 3.133700e+04) %calltmp1 = call double @bar(double 3.133700e+04)
%addtmp = fadd double %calltmp, %calltmp1 %addtmp = fadd double %calltmp, %calltmp1
ret double %addtmp ret double %addtmp
} }
</pre> </pre>
</div> </div>
@ -593,10 +593,10 @@ declare double @cos(double)
ready&gt; <b>cos(1.234);</b> ready&gt; <b>cos(1.234);</b>
Read top-level expression: Read top-level expression:
define double @""() { define double @1() {
entry: entry:
%calltmp = call double @cos(double 1.234000e+00) %calltmp = call double @cos(double 1.234000e+00)
ret double %calltmp ret double %calltmp
} }
</pre> </pre>
</div> </div>
@ -609,37 +609,37 @@ entry:
ready&gt; <b>^D</b> ready&gt; <b>^D</b>
; ModuleID = 'my cool jit' ; ModuleID = 'my cool jit'
define double @""() { define double @0() {
entry: entry:
%addtmp = fadd double 4.000000e+00, 5.000000e+00 %addtmp = fadd double 4.000000e+00, 5.000000e+00
ret double %addtmp ret double %addtmp
} }
define double @foo(double %a, double %b) { define double @foo(double %a, double %b) {
entry: entry:
%multmp = fmul double %a, %a %multmp = fmul double %a, %a
%multmp1 = fmul double 2.000000e+00, %a %multmp1 = fmul double 2.000000e+00, %a
%multmp2 = fmul double %multmp1, %b %multmp2 = fmul double %multmp1, %b
%addtmp = fadd double %multmp, %multmp2 %addtmp = fadd double %multmp, %multmp2
%multmp3 = fmul double %b, %b %multmp3 = fmul double %b, %b
%addtmp4 = fadd double %addtmp, %multmp3 %addtmp4 = fadd double %addtmp, %multmp3
ret double %addtmp4 ret double %addtmp4
} }
define double @bar(double %a) { define double @bar(double %a) {
entry: entry:
%calltmp = call double @foo(double %a, double 4.000000e+00) %calltmp = call double @foo(double %a, double 4.000000e+00)
%calltmp1 = call double @bar(double 3.133700e+04) %calltmp1 = call double @bar(double 3.133700e+04)
%addtmp = fadd double %calltmp, %calltmp1 %addtmp = fadd double %calltmp, %calltmp1
ret double %addtmp ret double %addtmp
} }
declare double @cos(double) declare double @cos(double)
define double @""() { define double @1() {
entry: entry:
%calltmp = call double @cos(double 1.234000e+00) %calltmp = call double @cos(double 1.234000e+00)
ret double %calltmp ret double %calltmp
} }
</pre> </pre>
</div> </div>
@ -670,10 +670,10 @@ our makefile/command line about which options to use:</p>
<div class="doc_code"> <div class="doc_code">
<pre> <pre>
# Compile # Compile
g++ -g -O3 toy.cpp `llvm-config --cppflags --ldflags --libs core` -o toy clang++ -g -O3 toy.cpp `llvm-config --cppflags --ldflags --libs core` -o toy
# Run # Run
./toy ./toy
</pre> </pre>
</div> </div>
@ -1081,13 +1081,13 @@ Value *CallExprAST::Codegen() {
if (ArgsV.back() == 0) return 0; if (ArgsV.back() == 0) return 0;
} }
return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp"); return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
} }
Function *PrototypeAST::Codegen() { Function *PrototypeAST::Codegen() {
// Make the function type: double(double,double) etc. // Make the function type: double(double,double) etc.
std::vector&lt;const Type*&gt; Doubles(Args.size(), std::vector&lt;Type*&gt; Doubles(Args.size(),
Type::getDoubleTy(getGlobalContext())); Type::getDoubleTy(getGlobalContext()));
FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()), FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
Doubles, false); Doubles, false);

View File

@ -343,9 +343,10 @@ code that is statically linked into your application.</p>
<div class="doc_code"> <div class="doc_code">
<pre> <pre>
ready&gt; <b>4+5;</b> ready&gt; <b>4+5;</b>
define double @""() { Read top-level expression:
define double @0() {
entry: entry:
ret double 9.000000e+00 ret double 9.000000e+00
} }
<em>Evaluated to 9.000000</em> <em>Evaluated to 9.000000</em>
@ -363,16 +364,17 @@ ready&gt; <b>def testfunc(x y) x + y*2; </b>
Read function definition: Read function definition:
define double @testfunc(double %x, double %y) { define double @testfunc(double %x, double %y) {
entry: entry:
%multmp = fmul double %y, 2.000000e+00 %multmp = fmul double %y, 2.000000e+00
%addtmp = fadd double %multmp, %x %addtmp = fadd double %multmp, %x
ret double %addtmp ret double %addtmp
} }
ready&gt; <b>testfunc(4, 10);</b> ready&gt; <b>testfunc(4, 10);</b>
define double @""() { Read top-level expression:
define double @1() {
entry: entry:
%calltmp = call double @testfunc(double 4.000000e+00, double 1.000000e+01) %calltmp = call double @testfunc(double 4.000000e+00, double 1.000000e+01)
ret double %calltmp ret double %calltmp
} }
<em>Evaluated to 24.000000</em> <em>Evaluated to 24.000000</em>
@ -404,21 +406,34 @@ Read extern:
declare double @cos(double) declare double @cos(double)
ready&gt; <b>sin(1.0);</b> ready&gt; <b>sin(1.0);</b>
Read top-level expression:
define double @2() {
entry:
ret double 0x3FEAED548F090CEE
}
<em>Evaluated to 0.841471</em> <em>Evaluated to 0.841471</em>
ready&gt; <b>def foo(x) sin(x)*sin(x) + cos(x)*cos(x);</b> ready&gt; <b>def foo(x) sin(x)*sin(x) + cos(x)*cos(x);</b>
Read function definition: Read function definition:
define double @foo(double %x) { define double @foo(double %x) {
entry: entry:
%calltmp = call double @sin(double %x) %calltmp = call double @sin(double %x)
%multmp = fmul double %calltmp, %calltmp %multmp = fmul double %calltmp, %calltmp
%calltmp2 = call double @cos(double %x) %calltmp2 = call double @cos(double %x)
%multmp4 = fmul double %calltmp2, %calltmp2 %multmp4 = fmul double %calltmp2, %calltmp2
%addtmp = fadd double %multmp, %multmp4 %addtmp = fadd double %multmp, %multmp4
ret double %addtmp ret double %addtmp
} }
ready&gt; <b>foo(4.0);</b> ready&gt; <b>foo(4.0);</b>
Read top-level expression:
define double @3() {
entry:
%calltmp = call double @foo(double 4.000000e+00)
ret double %calltmp
}
<em>Evaluated to 1.000000</em> <em>Evaluated to 1.000000</em>
</pre> </pre>
</div> </div>
@ -484,10 +499,10 @@ LLVM JIT and optimizer. To build this example, use:
<div class="doc_code"> <div class="doc_code">
<pre> <pre>
# Compile # Compile
g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy clang++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
# Run # Run
./toy ./toy
</pre> </pre>
</div> </div>
@ -509,9 +524,9 @@ at runtime.</p>
#include "llvm/Analysis/Verifier.h" #include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/Passes.h" #include "llvm/Analysis/Passes.h"
#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar.h"
#include "llvm/Support/IRBuilder.h" #include "llvm/Support/IRBuilder.h"
#include "llvm/Support/TargetSelect.h"
#include &lt;cstdio&gt; #include &lt;cstdio&gt;
#include &lt;string&gt; #include &lt;string&gt;
#include &lt;map&gt; #include &lt;map&gt;
@ -905,13 +920,13 @@ Value *CallExprAST::Codegen() {
if (ArgsV.back() == 0) return 0; if (ArgsV.back() == 0) return 0;
} }
return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp"); return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
} }
Function *PrototypeAST::Codegen() { Function *PrototypeAST::Codegen() {
// Make the function type: double(double,double) etc. // Make the function type: double(double,double) etc.
std::vector&lt;const Type*&gt; Doubles(Args.size(), std::vector&lt;Type*&gt; Doubles(Args.size(),
Type::getDoubleTy(getGlobalContext())); Type::getDoubleTy(getGlobalContext()));
FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()), FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
Doubles, false); Doubles, false);
@ -1013,6 +1028,9 @@ static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function. // Evaluate a top-level expression into an anonymous function.
if (FunctionAST *F = ParseTopLevelExpr()) { if (FunctionAST *F = ParseTopLevelExpr()) {
if (Function *LF = F-&gt;Codegen()) { if (Function *LF = F-&gt;Codegen()) {
fprintf(stderr, "Read top-level expression:");
LF->dump();
// JIT the function, returning a function pointer. // JIT the function, returning a function pointer.
void *FPtr = TheExecutionEngine-&gt;getPointerToFunction(LF); void *FPtr = TheExecutionEngine-&gt;getPointerToFunction(LF);
@ -1076,7 +1094,7 @@ int main() {
// Create the JIT. This takes ownership of the module. // Create the JIT. This takes ownership of the module.
std::string ErrStr; std::string ErrStr;
TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&amp;ErrStr).create(); TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&amp;ErrStr).create();
if (!TheExecutionEngine) { if (!TheExecutionEngine) {
fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str()); fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
exit(1); exit(1);

View File

@ -259,20 +259,20 @@ declare double @bar()
define double @baz(double %x) { define double @baz(double %x) {
entry: entry:
%ifcond = fcmp one double %x, 0.000000e+00 %ifcond = fcmp one double %x, 0.000000e+00
br i1 %ifcond, label %then, label %else br i1 %ifcond, label %then, label %else
then: ; preds = %entry then: ; preds = %entry
%calltmp = call double @foo() %calltmp = call double @foo()
br label %ifcont br label %ifcont
else: ; preds = %entry else: ; preds = %entry
%calltmp1 = call double @bar() %calltmp1 = call double @bar()
br label %ifcont br label %ifcont
ifcont: ; preds = %else, %then ifcont: ; preds = %else, %then
%iftmp = phi double [ %calltmp, %then ], [ %calltmp1, %else ] %iftmp = phi double [ %calltmp, %then ], [ %calltmp1, %else ]
ret double %iftmp ret double %iftmp
} }
</pre> </pre>
</div> </div>
@ -660,25 +660,25 @@ declare double @putchard(double)
define double @printstar(double %n) { define double @printstar(double %n) {
entry: entry:
; initial value = 1.0 (inlined into phi) ; initial value = 1.0 (inlined into phi)
br label %loop br label %loop
loop: ; preds = %loop, %entry loop: ; preds = %loop, %entry
%i = phi double [ 1.000000e+00, %entry ], [ %nextvar, %loop ] %i = phi double [ 1.000000e+00, %entry ], [ %nextvar, %loop ]
; body ; body
%calltmp = call double @putchard(double 4.200000e+01) %calltmp = call double @putchard(double 4.200000e+01)
; increment ; increment
%nextvar = fadd double %i, 1.000000e+00 %nextvar = fadd double %i, 1.000000e+00
; termination test ; termination test
%cmptmp = fcmp ult double %i, %n %cmptmp = fcmp ult double %i, %n
%booltmp = uitofp i1 %cmptmp to double %booltmp = uitofp i1 %cmptmp to double
%loopcond = fcmp one double %booltmp, 0.000000e+00 %loopcond = fcmp one double %booltmp, 0.000000e+00
br i1 %loopcond, label %loop, label %afterloop br i1 %loopcond, label %loop, label %afterloop
afterloop: ; preds = %loop afterloop: ; preds = %loop
; loop always returns 0.0 ; loop always returns 0.0
ret double 0.000000e+00 ret double 0.000000e+00
} }
</pre> </pre>
</div> </div>
@ -829,10 +829,11 @@ statement.</p>
</div> </div>
<p>With the code for the body of the loop complete, we just need to finish up <p>With the code for the body of the loop complete, we just need to finish up
the control flow for it. This code remembers the end block (for the phi node), then creates the block for the loop exit ("afterloop"). Based on the value of the the control flow for it. This code remembers the end block (for the phi node),
exit condition, it creates a conditional branch that chooses between executing then creates the block for the loop exit ("afterloop"). Based on the value of
the loop again and exiting the loop. Any future code is emitted in the the exit condition, it creates a conditional branch that chooses between
"afterloop" block, so it sets the insertion position to it.</p> executing the loop again and exiting the loop. Any future code is emitted in
the "afterloop" block, so it sets the insertion position to it.</p>
<div class="doc_code"> <div class="doc_code">
<pre> <pre>
@ -880,10 +881,10 @@ if/then/else and for expressions.. To build this example, use:
<div class="doc_code"> <div class="doc_code">
<pre> <pre>
# Compile # Compile
g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy clang++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
# Run # Run
./toy ./toy
</pre> </pre>
</div> </div>
@ -900,9 +901,9 @@ if/then/else and for expressions.. To build this example, use:
#include "llvm/Analysis/Verifier.h" #include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/Passes.h" #include "llvm/Analysis/Passes.h"
#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar.h"
#include "llvm/Support/IRBuilder.h" #include "llvm/Support/IRBuilder.h"
#include "llvm/Support/TargetSelect.h"
#include &lt;cstdio&gt; #include &lt;cstdio&gt;
#include &lt;string&gt; #include &lt;string&gt;
#include &lt;map&gt; #include &lt;map&gt;
@ -1397,7 +1398,7 @@ Value *CallExprAST::Codegen() {
if (ArgsV.back() == 0) return 0; if (ArgsV.back() == 0) return 0;
} }
return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp"); return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
} }
Value *IfExprAST::Codegen() { Value *IfExprAST::Codegen() {
@ -1546,8 +1547,8 @@ Value *ForExprAST::Codegen() {
Function *PrototypeAST::Codegen() { Function *PrototypeAST::Codegen() {
// Make the function type: double(double,double) etc. // Make the function type: double(double,double) etc.
std::vector&lt;const Type*&gt; Doubles(Args.size(), std::vector&lt;Type*&gt; Doubles(Args.size(),
Type::getDoubleTy(getGlobalContext())); Type::getDoubleTy(getGlobalContext()));
FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()), FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
Doubles, false); Doubles, false);

View File

@ -293,8 +293,8 @@ Value *BinaryExprAST::Codegen() {
Function *F = TheModule-&gt;getFunction(std::string("binary")+Op); Function *F = TheModule-&gt;getFunction(std::string("binary")+Op);
assert(F &amp;&amp; "binary operator not found!"); assert(F &amp;&amp; "binary operator not found!");
Value *Ops[] = { L, R }; Value *Ops[2] = { L, R };
return Builder.CreateCall(F, Ops, Ops+2, "binop");</b> return Builder.CreateCall(F, Ops, "binop");</b>
} }
</pre> </pre>
@ -505,7 +505,9 @@ defined to print out the specified value and a newline):</p>
<div class="doc_code"> <div class="doc_code">
<pre> <pre>
ready&gt; <b>extern printd(x);</b> ready&gt; <b>extern printd(x);</b>
Read extern: declare double @printd(double) Read extern:
declare double @printd(double)
ready&gt; <b>def binary : 1 (x y) 0; # Low-precedence operator that ignores operands.</b> ready&gt; <b>def binary : 1 (x y) 0; # Low-precedence operator that ignores operands.</b>
.. ..
ready&gt; <b>printd(123) : printd(456) : printd(789);</b> ready&gt; <b>printd(123) : printd(456) : printd(789);</b>
@ -555,6 +557,9 @@ def binary&amp; 6 (LHS RHS)
def binary = 9 (LHS RHS) def binary = 9 (LHS RHS)
!(LHS &lt; RHS | LHS &gt; RHS); !(LHS &lt; RHS | LHS &gt; RHS);
# Define ':' for sequencing: as a low-precedence operator that ignores operands
# and just returns the RHS.
def binary : 1 (x y) y;
</pre> </pre>
</div> </div>
@ -579,9 +584,10 @@ def printdensity(d)
else else
putchard(42); # '*'</b> putchard(42); # '*'</b>
... ...
ready&gt; <b>printdensity(1): printdensity(2): printdensity(3) : ready&gt; <b>printdensity(1): printdensity(2): printdensity(3):
printdensity(4): printdensity(5): printdensity(9): putchard(10);</b> printdensity(4): printdensity(5): printdensity(9):
*++.. putchard(10);</b>
**++.
Evaluated to 0.000000 Evaluated to 0.000000
</pre> </pre>
</div> </div>
@ -593,7 +599,7 @@ converge:</p>
<div class="doc_code"> <div class="doc_code">
<pre> <pre>
# determine whether the specific location diverges. # Determine whether the specific location diverges.
# Solve for z = z^2 + c in the complex plane. # Solve for z = z^2 + c in the complex plane.
def mandleconverger(real imag iters creal cimag) def mandleconverger(real imag iters creal cimag)
if iters &gt; 255 | (real*real + imag*imag &gt; 4) then if iters &gt; 255 | (real*real + imag*imag &gt; 4) then
@ -603,25 +609,25 @@ def mandleconverger(real imag iters creal cimag)
2*real*imag + cimag, 2*real*imag + cimag,
iters+1, creal, cimag); iters+1, creal, cimag);
# return the number of iterations required for the iteration to escape # Return the number of iterations required for the iteration to escape
def mandleconverge(real imag) def mandleconverge(real imag)
mandleconverger(real, imag, 0, real, imag); mandleconverger(real, imag, 0, real, imag);
</pre> </pre>
</div> </div>
<p>This "z = z<sup>2</sup> + c" function is a beautiful little creature that is the basis <p>This "<code>z = z<sup>2</sup> + c</code>" function is a beautiful little
for computation of the <a creature that is the basis for computation of
href="http://en.wikipedia.org/wiki/Mandelbrot_set">Mandelbrot Set</a>. Our the <a href="http://en.wikipedia.org/wiki/Mandelbrot_set">Mandelbrot Set</a>.
<tt>mandelconverge</tt> function returns the number of iterations that it takes Our <tt>mandelconverge</tt> function returns the number of iterations that it
for a complex orbit to escape, saturating to 255. This is not a very useful takes for a complex orbit to escape, saturating to 255. This is not a very
function by itself, but if you plot its value over a two-dimensional plane, useful function by itself, but if you plot its value over a two-dimensional
you can see the Mandelbrot set. Given that we are limited to using putchard plane, you can see the Mandelbrot set. Given that we are limited to using
here, our amazing graphical output is limited, but we can whip together putchard here, our amazing graphical output is limited, but we can whip together
something using the density plotter above:</p> something using the density plotter above:</p>
<div class="doc_code"> <div class="doc_code">
<pre> <pre>
# compute and plot the mandlebrot set with the specified 2 dimensional range # Compute and plot the mandlebrot set with the specified 2 dimensional range
# info. # info.
def mandelhelp(xmin xmax xstep ymin ymax ystep) def mandelhelp(xmin xmax xstep ymin ymax ystep)
for y = ymin, y &lt; ymax, ystep in ( for y = ymin, y &lt; ymax, ystep in (
@ -808,10 +814,10 @@ if/then/else and for expressions.. To build this example, use:
<div class="doc_code"> <div class="doc_code">
<pre> <pre>
# Compile # Compile
g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy clang++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
# Run # Run
./toy ./toy
</pre> </pre>
</div> </div>
@ -834,9 +840,9 @@ library, although doing that will cause problems on Windows.</p>
#include "llvm/Analysis/Verifier.h" #include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/Passes.h" #include "llvm/Analysis/Passes.h"
#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar.h"
#include "llvm/Support/IRBuilder.h" #include "llvm/Support/IRBuilder.h"
#include "llvm/Support/TargetSelect.h"
#include &lt;cstdio&gt; #include &lt;cstdio&gt;
#include &lt;string&gt; #include &lt;string&gt;
#include &lt;map&gt; #include &lt;map&gt;
@ -1415,8 +1421,8 @@ Value *BinaryExprAST::Codegen() {
Function *F = TheModule-&gt;getFunction(std::string("binary")+Op); Function *F = TheModule-&gt;getFunction(std::string("binary")+Op);
assert(F &amp;&amp; "binary operator not found!"); assert(F &amp;&amp; "binary operator not found!");
Value *Ops[] = { L, R }; Value *Ops[2] = { L, R };
return Builder.CreateCall(F, Ops, Ops+2, "binop"); return Builder.CreateCall(F, Ops, "binop");
} }
Value *CallExprAST::Codegen() { Value *CallExprAST::Codegen() {
@ -1435,7 +1441,7 @@ Value *CallExprAST::Codegen() {
if (ArgsV.back() == 0) return 0; if (ArgsV.back() == 0) return 0;
} }
return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp"); return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
} }
Value *IfExprAST::Codegen() { Value *IfExprAST::Codegen() {
@ -1584,8 +1590,8 @@ Value *ForExprAST::Codegen() {
Function *PrototypeAST::Codegen() { Function *PrototypeAST::Codegen() {
// Make the function type: double(double,double) etc. // Make the function type: double(double,double) etc.
std::vector&lt;const Type*&gt; Doubles(Args.size(), std::vector&lt;Type*&gt; Doubles(Args.size(),
Type::getDoubleTy(getGlobalContext())); Type::getDoubleTy(getGlobalContext()));
FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()), FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
Doubles, false); Doubles, false);

View File

@ -102,19 +102,19 @@ The LLVM IR that we want for this example looks like this:</p>
define i32 @test(i1 %Condition) { define i32 @test(i1 %Condition) {
entry: entry:
br i1 %Condition, label %cond_true, label %cond_false br i1 %Condition, label %cond_true, label %cond_false
cond_true: cond_true:
%X.0 = load i32* @G %X.0 = load i32* @G
br label %cond_next br label %cond_next
cond_false: cond_false:
%X.1 = load i32* @H %X.1 = load i32* @H
br label %cond_next br label %cond_next
cond_next: cond_next:
%X.2 = phi i32 [ %X.1, %cond_false ], [ %X.0, %cond_true ] %X.2 = phi i32 [ %X.1, %cond_false ], [ %X.0, %cond_true ]
ret i32 %X.2 ret i32 %X.2
} }
</pre> </pre>
</div> </div>
@ -174,12 +174,12 @@ being declared with global variable definitions, they are declared with the
<pre> <pre>
define i32 @example() { define i32 @example() {
entry: entry:
%X = alloca i32 ; type of %X is i32*. %X = alloca i32 ; type of %X is i32*.
... ...
%tmp = load i32* %X ; load the stack value %X from the stack. %tmp = load i32* %X ; load the stack value %X from the stack.
%tmp2 = add i32 %tmp, 1 ; increment it %tmp2 = add i32 %tmp, 1 ; increment it
store i32 %tmp2, i32* %X ; store it back store i32 %tmp2, i32* %X ; store it back
... ...
</pre> </pre>
</div> </div>
@ -196,22 +196,22 @@ example to use the alloca technique to avoid using a PHI node:</p>
define i32 @test(i1 %Condition) { define i32 @test(i1 %Condition) {
entry: entry:
%X = alloca i32 ; type of %X is i32*. %X = alloca i32 ; type of %X is i32*.
br i1 %Condition, label %cond_true, label %cond_false br i1 %Condition, label %cond_true, label %cond_false
cond_true: cond_true:
%X.0 = load i32* @G %X.0 = load i32* @G
store i32 %X.0, i32* %X ; Update X store i32 %X.0, i32* %X ; Update X
br label %cond_next br label %cond_next
cond_false: cond_false:
%X.1 = load i32* @H %X.1 = load i32* @H
store i32 %X.1, i32* %X ; Update X store i32 %X.1, i32* %X ; Update X
br label %cond_next br label %cond_next
cond_next: cond_next:
%X.2 = load i32* %X ; Read X %X.2 = load i32* %X ; Read X
ret i32 %X.2 ret i32 %X.2
} }
</pre> </pre>
</div> </div>
@ -242,19 +242,19 @@ $ <b>llvm-as &lt; example.ll | opt -mem2reg | llvm-dis</b>
define i32 @test(i1 %Condition) { define i32 @test(i1 %Condition) {
entry: entry:
br i1 %Condition, label %cond_true, label %cond_false br i1 %Condition, label %cond_true, label %cond_false
cond_true: cond_true:
%X.0 = load i32* @G %X.0 = load i32* @G
br label %cond_next br label %cond_next
cond_false: cond_false:
%X.1 = load i32* @H %X.1 = load i32* @H
br label %cond_next br label %cond_next
cond_next: cond_next:
%X.01 = phi i32 [ %X.1, %cond_false ], [ %X.0, %cond_true ] %X.01 = phi i32 [ %X.1, %cond_false ], [ %X.0, %cond_true ]
ret i32 %X.01 ret i32 %X.01
} }
</pre> </pre>
</div> </div>
@ -542,30 +542,30 @@ recursive fib function. Before the optimization:</p>
<pre> <pre>
define double @fib(double %x) { define double @fib(double %x) {
entry: entry:
<b>%x1 = alloca double <b>%x1 = alloca double
store double %x, double* %x1 store double %x, double* %x1
%x2 = load double* %x1</b> %x2 = load double* %x1</b>
%cmptmp = fcmp ult double %x2, 3.000000e+00 %cmptmp = fcmp ult double %x2, 3.000000e+00
%booltmp = uitofp i1 %cmptmp to double %booltmp = uitofp i1 %cmptmp to double
%ifcond = fcmp one double %booltmp, 0.000000e+00 %ifcond = fcmp one double %booltmp, 0.000000e+00
br i1 %ifcond, label %then, label %else br i1 %ifcond, label %then, label %else
then: ; preds = %entry then: ; preds = %entry
br label %ifcont br label %ifcont
else: ; preds = %entry else: ; preds = %entry
<b>%x3 = load double* %x1</b> <b>%x3 = load double* %x1</b>
%subtmp = fsub double %x3, 1.000000e+00 %subtmp = fsub double %x3, 1.000000e+00
%calltmp = call double @fib(double %subtmp) %calltmp = call double @fib(double %subtmp)
<b>%x4 = load double* %x1</b> <b>%x4 = load double* %x1</b>
%subtmp5 = fsub double %x4, 2.000000e+00 %subtmp5 = fsub double %x4, 2.000000e+00
%calltmp6 = call double @fib(double %subtmp5) %calltmp6 = call double @fib(double %subtmp5)
%addtmp = fadd double %calltmp, %calltmp6 %addtmp = fadd double %calltmp, %calltmp6
br label %ifcont br label %ifcont
ifcont: ; preds = %else, %then ifcont: ; preds = %else, %then
%iftmp = phi double [ 1.000000e+00, %then ], [ %addtmp, %else ] %iftmp = phi double [ 1.000000e+00, %then ], [ %addtmp, %else ]
ret double %iftmp ret double %iftmp
} }
</pre> </pre>
</div> </div>
@ -584,25 +584,25 @@ PHI node for it, so we still just make the PHI.</p>
<pre> <pre>
define double @fib(double %x) { define double @fib(double %x) {
entry: entry:
%cmptmp = fcmp ult double <b>%x</b>, 3.000000e+00 %cmptmp = fcmp ult double <b>%x</b>, 3.000000e+00
%booltmp = uitofp i1 %cmptmp to double %booltmp = uitofp i1 %cmptmp to double
%ifcond = fcmp one double %booltmp, 0.000000e+00 %ifcond = fcmp one double %booltmp, 0.000000e+00
br i1 %ifcond, label %then, label %else br i1 %ifcond, label %then, label %else
then: then:
br label %ifcont br label %ifcont
else: else:
%subtmp = fsub double <b>%x</b>, 1.000000e+00 %subtmp = fsub double <b>%x</b>, 1.000000e+00
%calltmp = call double @fib(double %subtmp) %calltmp = call double @fib(double %subtmp)
%subtmp5 = fsub double <b>%x</b>, 2.000000e+00 %subtmp5 = fsub double <b>%x</b>, 2.000000e+00
%calltmp6 = call double @fib(double %subtmp5) %calltmp6 = call double @fib(double %subtmp5)
%addtmp = fadd double %calltmp, %calltmp6 %addtmp = fadd double %calltmp, %calltmp6
br label %ifcont br label %ifcont
ifcont: ; preds = %else, %then ifcont: ; preds = %else, %then
%iftmp = phi double [ 1.000000e+00, %then ], [ %addtmp, %else ] %iftmp = phi double [ 1.000000e+00, %then ], [ %addtmp, %else ]
ret double %iftmp ret double %iftmp
} }
</pre> </pre>
</div> </div>
@ -617,21 +617,21 @@ such blatent inefficiencies :).</p>
<pre> <pre>
define double @fib(double %x) { define double @fib(double %x) {
entry: entry:
%cmptmp = fcmp ult double %x, 3.000000e+00 %cmptmp = fcmp ult double %x, 3.000000e+00
%booltmp = uitofp i1 %cmptmp to double %booltmp = uitofp i1 %cmptmp to double
%ifcond = fcmp ueq double %booltmp, 0.000000e+00 %ifcond = fcmp ueq double %booltmp, 0.000000e+00
br i1 %ifcond, label %else, label %ifcont br i1 %ifcond, label %else, label %ifcont
else: else:
%subtmp = fsub double %x, 1.000000e+00 %subtmp = fsub double %x, 1.000000e+00
%calltmp = call double @fib(double %subtmp) %calltmp = call double @fib(double %subtmp)
%subtmp5 = fsub double %x, 2.000000e+00 %subtmp5 = fsub double %x, 2.000000e+00
%calltmp6 = call double @fib(double %subtmp5) %calltmp6 = call double @fib(double %subtmp5)
%addtmp = fadd double %calltmp, %calltmp6 %addtmp = fadd double %calltmp, %calltmp6
ret double %addtmp ret double %addtmp
ifcont: ifcont:
ret double 1.000000e+00 ret double 1.000000e+00
} }
</pre> </pre>
</div> </div>
@ -988,10 +988,10 @@ variables and var/in support. To build this example, use:
<div class="doc_code"> <div class="doc_code">
<pre> <pre>
# Compile # Compile
g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy clang++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
# Run # Run
./toy ./toy
</pre> </pre>
</div> </div>
@ -1008,9 +1008,9 @@ variables and var/in support. To build this example, use:
#include "llvm/Analysis/Verifier.h" #include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/Passes.h" #include "llvm/Analysis/Passes.h"
#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar.h"
#include "llvm/Support/IRBuilder.h" #include "llvm/Support/IRBuilder.h"
#include "llvm/Support/TargetSelect.h"
#include &lt;cstdio&gt; #include &lt;cstdio&gt;
#include &lt;string&gt; #include &lt;string&gt;
#include &lt;map&gt; #include &lt;map&gt;
@ -1686,8 +1686,8 @@ Value *BinaryExprAST::Codegen() {
Function *F = TheModule-&gt;getFunction(std::string("binary")+Op); Function *F = TheModule-&gt;getFunction(std::string("binary")+Op);
assert(F &amp;&amp; "binary operator not found!"); assert(F &amp;&amp; "binary operator not found!");
Value *Ops[] = { L, R }; Value *Ops[2] = { L, R };
return Builder.CreateCall(F, Ops, Ops+2, "binop"); return Builder.CreateCall(F, Ops, "binop");
} }
Value *CallExprAST::Codegen() { Value *CallExprAST::Codegen() {
@ -1706,7 +1706,7 @@ Value *CallExprAST::Codegen() {
if (ArgsV.back() == 0) return 0; if (ArgsV.back() == 0) return 0;
} }
return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp"); return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
} }
Value *IfExprAST::Codegen() { Value *IfExprAST::Codegen() {
@ -1907,8 +1907,8 @@ Value *VarExprAST::Codegen() {
Function *PrototypeAST::Codegen() { Function *PrototypeAST::Codegen() {
// Make the function type: double(double,double) etc. // Make the function type: double(double,double) etc.
std::vector&lt;const Type*&gt; Doubles(Args.size(), std::vector&lt;Type*&gt; Doubles(Args.size(),
Type::getDoubleTy(getGlobalContext())); Type::getDoubleTy(getGlobalContext()));
FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()), FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
Doubles, false); Doubles, false);