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

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


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142123 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bill Wendling 2011-10-16 08:06:54 +00:00
parent b53fa8bf19
commit 545a2beb44
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">
<pre>
# Compile
g++ -g -O3 toy.cpp
# Run
./a.out
# Compile
clang++ -g -O3 toy.cpp
# Run
./a.out
</pre>
</div>

View File

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

View File

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

View File

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

View File

@ -293,8 +293,8 @@ Value *BinaryExprAST::Codegen() {
Function *F = TheModule-&gt;getFunction(std::string("binary")+Op);
assert(F &amp;&amp; "binary operator not found!");
Value *Ops[] = { L, R };
return Builder.CreateCall(F, Ops, Ops+2, "binop");</b>
Value *Ops[2] = { L, R };
return Builder.CreateCall(F, Ops, "binop");</b>
}
</pre>
@ -505,7 +505,9 @@ defined to print out the specified value and a newline):</p>
<div class="doc_code">
<pre>
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>printd(123) : printd(456) : printd(789);</b>
@ -555,6 +557,9 @@ def binary&amp; 6 (LHS RHS)
def binary = 9 (LHS 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>
</div>
@ -579,9 +584,10 @@ def printdensity(d)
else
putchard(42); # '*'</b>
...
ready&gt; <b>printdensity(1): printdensity(2): printdensity(3) :
printdensity(4): printdensity(5): printdensity(9): putchard(10);</b>
*++..
ready&gt; <b>printdensity(1): printdensity(2): printdensity(3):
printdensity(4): printdensity(5): printdensity(9):
putchard(10);</b>
**++.
Evaluated to 0.000000
</pre>
</div>
@ -593,7 +599,7 @@ converge:</p>
<div class="doc_code">
<pre>
# determine whether the specific location diverges.
# Determine whether the specific location diverges.
# Solve for z = z^2 + c in the complex plane.
def mandleconverger(real imag iters creal cimag)
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,
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)
mandleconverger(real, imag, 0, real, imag);
</pre>
</div>
<p>This "z = z<sup>2</sup> + c" function is a beautiful little creature that is the basis
for computation of the <a
href="http://en.wikipedia.org/wiki/Mandelbrot_set">Mandelbrot Set</a>. Our
<tt>mandelconverge</tt> function returns the number of iterations that it takes
for a complex orbit to escape, saturating to 255. This is not a very useful
function by itself, but if you plot its value over a two-dimensional plane,
you can see the Mandelbrot set. Given that we are limited to using putchard
here, our amazing graphical output is limited, but we can whip together
<p>This "<code>z = z<sup>2</sup> + c</code>" function is a beautiful little
creature that is the basis for computation of
the <a href="http://en.wikipedia.org/wiki/Mandelbrot_set">Mandelbrot Set</a>.
Our <tt>mandelconverge</tt> function returns the number of iterations that it
takes for a complex orbit to escape, saturating to 255. This is not a very
useful function by itself, but if you plot its value over a two-dimensional
plane, you can see the Mandelbrot set. Given that we are limited to using
putchard here, our amazing graphical output is limited, but we can whip together
something using the density plotter above:</p>
<div class="doc_code">
<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.
def mandelhelp(xmin xmax xstep ymin ymax ystep)
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">
<pre>
# Compile
g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
# Run
./toy
# Compile
clang++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
# Run
./toy
</pre>
</div>
@ -834,9 +840,9 @@ library, although doing that will cause problems on Windows.</p>
#include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/IRBuilder.h"
#include "llvm/Support/TargetSelect.h"
#include &lt;cstdio&gt;
#include &lt;string&gt;
#include &lt;map&gt;
@ -1415,8 +1421,8 @@ Value *BinaryExprAST::Codegen() {
Function *F = TheModule-&gt;getFunction(std::string("binary")+Op);
assert(F &amp;&amp; "binary operator not found!");
Value *Ops[] = { L, R };
return Builder.CreateCall(F, Ops, Ops+2, "binop");
Value *Ops[2] = { L, R };
return Builder.CreateCall(F, Ops, "binop");
}
Value *CallExprAST::Codegen() {
@ -1435,7 +1441,7 @@ Value *CallExprAST::Codegen() {
if (ArgsV.back() == 0) return 0;
}
return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp");
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
}
Value *IfExprAST::Codegen() {
@ -1584,8 +1590,8 @@ Value *ForExprAST::Codegen() {
Function *PrototypeAST::Codegen() {
// Make the function type: double(double,double) etc.
std::vector&lt;const Type*&gt; Doubles(Args.size(),
Type::getDoubleTy(getGlobalContext()));
std::vector&lt;Type*&gt; Doubles(Args.size(),
Type::getDoubleTy(getGlobalContext()));
FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
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) {
entry:
br i1 %Condition, label %cond_true, label %cond_false
br i1 %Condition, label %cond_true, label %cond_false
cond_true:
%X.0 = load i32* @G
br label %cond_next
%X.0 = load i32* @G
br label %cond_next
cond_false:
%X.1 = load i32* @H
br label %cond_next
%X.1 = load i32* @H
br label %cond_next
cond_next:
%X.2 = phi i32 [ %X.1, %cond_false ], [ %X.0, %cond_true ]
ret i32 %X.2
%X.2 = phi i32 [ %X.1, %cond_false ], [ %X.0, %cond_true ]
ret i32 %X.2
}
</pre>
</div>
@ -174,12 +174,12 @@ being declared with global variable definitions, they are declared with the
<pre>
define i32 @example() {
entry:
%X = alloca i32 ; type of %X is i32*.
...
%tmp = load i32* %X ; load the stack value %X from the stack.
%tmp2 = add i32 %tmp, 1 ; increment it
store i32 %tmp2, i32* %X ; store it back
...
%X = alloca i32 ; type of %X is i32*.
...
%tmp = load i32* %X ; load the stack value %X from the stack.
%tmp2 = add i32 %tmp, 1 ; increment it
store i32 %tmp2, i32* %X ; store it back
...
</pre>
</div>
@ -196,22 +196,22 @@ example to use the alloca technique to avoid using a PHI node:</p>
define i32 @test(i1 %Condition) {
entry:
%X = alloca i32 ; type of %X is i32*.
br i1 %Condition, label %cond_true, label %cond_false
%X = alloca i32 ; type of %X is i32*.
br i1 %Condition, label %cond_true, label %cond_false
cond_true:
%X.0 = load i32* @G
store i32 %X.0, i32* %X ; Update X
br label %cond_next
%X.0 = load i32* @G
store i32 %X.0, i32* %X ; Update X
br label %cond_next
cond_false:
%X.1 = load i32* @H
store i32 %X.1, i32* %X ; Update X
br label %cond_next
%X.1 = load i32* @H
store i32 %X.1, i32* %X ; Update X
br label %cond_next
cond_next:
%X.2 = load i32* %X ; Read X
ret i32 %X.2
%X.2 = load i32* %X ; Read X
ret i32 %X.2
}
</pre>
</div>
@ -242,19 +242,19 @@ $ <b>llvm-as &lt; example.ll | opt -mem2reg | llvm-dis</b>
define i32 @test(i1 %Condition) {
entry:
br i1 %Condition, label %cond_true, label %cond_false
br i1 %Condition, label %cond_true, label %cond_false
cond_true:
%X.0 = load i32* @G
br label %cond_next
%X.0 = load i32* @G
br label %cond_next
cond_false:
%X.1 = load i32* @H
br label %cond_next
%X.1 = load i32* @H
br label %cond_next
cond_next:
%X.01 = phi i32 [ %X.1, %cond_false ], [ %X.0, %cond_true ]
ret i32 %X.01
%X.01 = phi i32 [ %X.1, %cond_false ], [ %X.0, %cond_true ]
ret i32 %X.01
}
</pre>
</div>
@ -542,30 +542,30 @@ recursive fib function. Before the optimization:</p>
<pre>
define double @fib(double %x) {
entry:
<b>%x1 = alloca double
store double %x, double* %x1
%x2 = load double* %x1</b>
%cmptmp = fcmp ult double %x2, 3.000000e+00
%booltmp = uitofp i1 %cmptmp to double
%ifcond = fcmp one double %booltmp, 0.000000e+00
br i1 %ifcond, label %then, label %else
<b>%x1 = alloca double
store double %x, double* %x1
%x2 = load double* %x1</b>
%cmptmp = fcmp ult double %x2, 3.000000e+00
%booltmp = uitofp i1 %cmptmp to double
%ifcond = fcmp one double %booltmp, 0.000000e+00
br i1 %ifcond, label %then, label %else
then: ; preds = %entry
br label %ifcont
br label %ifcont
else: ; preds = %entry
<b>%x3 = load double* %x1</b>
%subtmp = fsub double %x3, 1.000000e+00
%calltmp = call double @fib(double %subtmp)
<b>%x4 = load double* %x1</b>
%subtmp5 = fsub double %x4, 2.000000e+00
%calltmp6 = call double @fib(double %subtmp5)
%addtmp = fadd double %calltmp, %calltmp6
br label %ifcont
<b>%x3 = load double* %x1</b>
%subtmp = fsub double %x3, 1.000000e+00
%calltmp = call double @fib(double %subtmp)
<b>%x4 = load double* %x1</b>
%subtmp5 = fsub double %x4, 2.000000e+00
%calltmp6 = call double @fib(double %subtmp5)
%addtmp = fadd double %calltmp, %calltmp6
br label %ifcont
ifcont: ; preds = %else, %then
%iftmp = phi double [ 1.000000e+00, %then ], [ %addtmp, %else ]
ret double %iftmp
%iftmp = phi double [ 1.000000e+00, %then ], [ %addtmp, %else ]
ret double %iftmp
}
</pre>
</div>
@ -584,25 +584,25 @@ PHI node for it, so we still just make the PHI.</p>
<pre>
define double @fib(double %x) {
entry:
%cmptmp = fcmp ult double <b>%x</b>, 3.000000e+00
%booltmp = uitofp i1 %cmptmp to double
%ifcond = fcmp one double %booltmp, 0.000000e+00
br i1 %ifcond, label %then, label %else
%cmptmp = fcmp ult double <b>%x</b>, 3.000000e+00
%booltmp = uitofp i1 %cmptmp to double
%ifcond = fcmp one double %booltmp, 0.000000e+00
br i1 %ifcond, label %then, label %else
then:
br label %ifcont
br label %ifcont
else:
%subtmp = fsub double <b>%x</b>, 1.000000e+00
%calltmp = call double @fib(double %subtmp)
%subtmp5 = fsub double <b>%x</b>, 2.000000e+00
%calltmp6 = call double @fib(double %subtmp5)
%addtmp = fadd double %calltmp, %calltmp6
br label %ifcont
%subtmp = fsub double <b>%x</b>, 1.000000e+00
%calltmp = call double @fib(double %subtmp)
%subtmp5 = fsub double <b>%x</b>, 2.000000e+00
%calltmp6 = call double @fib(double %subtmp5)
%addtmp = fadd double %calltmp, %calltmp6
br label %ifcont
ifcont: ; preds = %else, %then
%iftmp = phi double [ 1.000000e+00, %then ], [ %addtmp, %else ]
ret double %iftmp
%iftmp = phi double [ 1.000000e+00, %then ], [ %addtmp, %else ]
ret double %iftmp
}
</pre>
</div>
@ -617,21 +617,21 @@ such blatent inefficiencies :).</p>
<pre>
define double @fib(double %x) {
entry:
%cmptmp = fcmp ult double %x, 3.000000e+00
%booltmp = uitofp i1 %cmptmp to double
%ifcond = fcmp ueq double %booltmp, 0.000000e+00
br i1 %ifcond, label %else, label %ifcont
%cmptmp = fcmp ult double %x, 3.000000e+00
%booltmp = uitofp i1 %cmptmp to double
%ifcond = fcmp ueq double %booltmp, 0.000000e+00
br i1 %ifcond, label %else, label %ifcont
else:
%subtmp = fsub double %x, 1.000000e+00
%calltmp = call double @fib(double %subtmp)
%subtmp5 = fsub double %x, 2.000000e+00
%calltmp6 = call double @fib(double %subtmp5)
%addtmp = fadd double %calltmp, %calltmp6
ret double %addtmp
%subtmp = fsub double %x, 1.000000e+00
%calltmp = call double @fib(double %subtmp)
%subtmp5 = fsub double %x, 2.000000e+00
%calltmp6 = call double @fib(double %subtmp5)
%addtmp = fadd double %calltmp, %calltmp6
ret double %addtmp
ifcont:
ret double 1.000000e+00
ret double 1.000000e+00
}
</pre>
</div>
@ -988,10 +988,10 @@ variables and var/in support. To build this example, use:
<div class="doc_code">
<pre>
# Compile
g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
# Run
./toy
# Compile
clang++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
# Run
./toy
</pre>
</div>
@ -1008,9 +1008,9 @@ variables and var/in support. To build this example, use:
#include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/IRBuilder.h"
#include "llvm/Support/TargetSelect.h"
#include &lt;cstdio&gt;
#include &lt;string&gt;
#include &lt;map&gt;
@ -1686,8 +1686,8 @@ Value *BinaryExprAST::Codegen() {
Function *F = TheModule-&gt;getFunction(std::string("binary")+Op);
assert(F &amp;&amp; "binary operator not found!");
Value *Ops[] = { L, R };
return Builder.CreateCall(F, Ops, Ops+2, "binop");
Value *Ops[2] = { L, R };
return Builder.CreateCall(F, Ops, "binop");
}
Value *CallExprAST::Codegen() {
@ -1706,7 +1706,7 @@ Value *CallExprAST::Codegen() {
if (ArgsV.back() == 0) return 0;
}
return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp");
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
}
Value *IfExprAST::Codegen() {
@ -1907,8 +1907,8 @@ Value *VarExprAST::Codegen() {
Function *PrototypeAST::Codegen() {
// Make the function type: double(double,double) etc.
std::vector&lt;const Type*&gt; Doubles(Args.size(),
Type::getDoubleTy(getGlobalContext()));
std::vector&lt;Type*&gt; Doubles(Args.size(),
Type::getDoubleTy(getGlobalContext()));
FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
Doubles, false);