Removed extranaeous code highlighting tags
This commit is contained in:
parent
0b63bd7a9f
commit
d322b66a69
5 changed files with 14 additions and 14 deletions
|
|
@ -405,7 +405,7 @@ LLVM Function object that is ready to go for us.
|
||||||
|
|
||||||
# Create a new basic block to start insertion into.
|
# Create a new basic block to start insertion into.
|
||||||
block = function.append_basic_block('entry')
|
block = function.append_basic_block('entry')
|
||||||
global g_llvm_builder g_llvm_builder = Builder.new(block) {% endhighlight %}
|
global g_llvm_builder g_llvm_builder = Builder.new(block)
|
||||||
|
|
||||||
Now we get to the point where ``g_llvm_builder`` is set up. The first
|
Now we get to the point where ``g_llvm_builder`` is set up. The first
|
||||||
line creates a new `basic
|
line creates a new `basic
|
||||||
|
|
@ -419,7 +419,7 @@ LLVM Function object that is ready to go for us.
|
||||||
don't have any control flow, our functions will only contain one block
|
don't have any control flow, our functions will only contain one block
|
||||||
at this point. We'll fix this in `Chapter 5 <PythonLangImpl5.html>`_ :).
|
at this point. We'll fix this in `Chapter 5 <PythonLangImpl5.html>`_ :).
|
||||||
|
|
||||||
{% highlight python %} # Finish off the function. try: return_value =
|
# Finish off the function. try: return_value =
|
||||||
self.body.CodeGen() g_llvm_builder.ret(return_value)
|
self.body.CodeGen() g_llvm_builder.ret(return_value)
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
|
||||||
|
|
@ -270,7 +270,7 @@ this:
|
||||||
|
|
||||||
With just these two changes, lets see how Kaleidoscope works now!
|
With just these two changes, lets see how Kaleidoscope works now!
|
||||||
|
|
||||||
{% highlight python %} ready> 4+5 Read a top level expression: define
|
ready> 4+5 Read a top level expression: define
|
||||||
double @0() { entry: ret double 9.000000e+00 }
|
double @0() { entry: ret double 9.000000e+00 }
|
||||||
|
|
||||||
Evaluated to: 9.0
|
Evaluated to: 9.0
|
||||||
|
|
@ -359,14 +359,14 @@ example, we can create a C file with the following simple function:
|
||||||
|
|
||||||
We can then compile this into a shared library with GCC:
|
We can then compile this into a shared library with GCC:
|
||||||
|
|
||||||
{% highlight bash %} gcc -shared -fPIC -o putchard.so putchard.c {%
|
gcc -shared -fPIC -o putchard.so putchard.c {%
|
||||||
endhighlight %}
|
endhighlight %}
|
||||||
|
|
||||||
Now we can load this library into the Python process using
|
Now we can load this library into the Python process using
|
||||||
``llvm.core.load_library_permanently`` and access it from Kaleidoscope
|
``llvm.core.load_library_permanently`` and access it from Kaleidoscope
|
||||||
to produce simple output to the console:
|
to produce simple output to the console:
|
||||||
|
|
||||||
{% highlight python %} >>> import llvm.core >>>
|
>>> import llvm.core >>>
|
||||||
llvm.core.load_library_permanently('/home/max/llvmpy-tutorial/putchard.so')
|
llvm.core.load_library_permanently('/home/max/llvmpy-tutorial/putchard.so')
|
||||||
>>> import kaleidoscope >>> kaleidoscope.main() ready> extern
|
>>> import kaleidoscope >>> kaleidoscope.main() ready> extern
|
||||||
putchard(x) Read an extern: declare double @putchard(double)
|
putchard(x) Read an extern: declare double @putchard(double)
|
||||||
|
|
|
||||||
|
|
@ -610,7 +610,7 @@ expression for the loop value:
|
||||||
of multiple blocks (e.g. if it contains an if/then/else or a for/in
|
of multiple blocks (e.g. if it contains an if/then/else or a for/in
|
||||||
expression).
|
expression).
|
||||||
|
|
||||||
{% highlight python %} # Make the new basic block for the loop header,
|
# Make the new basic block for the loop header,
|
||||||
inserting after current # block. function =
|
inserting after current # block. function =
|
||||||
g_llvm_builder.basic_block.function pre_header_block =
|
g_llvm_builder.basic_block.function pre_header_block =
|
||||||
g_llvm_builder.basic_block loop_block =
|
g_llvm_builder.basic_block loop_block =
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ keywords:
|
||||||
``PrototypeNode``. To represent our new user-defined operators as
|
``PrototypeNode``. To represent our new user-defined operators as
|
||||||
prototypes, we have to extend the ``PrototypeNode`` like this:
|
prototypes, we have to extend the ``PrototypeNode`` like this:
|
||||||
|
|
||||||
{% highlight python %} # This class represents the "prototype" for a
|
# This class represents the "prototype" for a
|
||||||
function, which captures its name, # and its argument names (thus
|
function, which captures its name, # and its argument names (thus
|
||||||
implicitly the number of arguments the function # takes), as well as if
|
implicitly the number of arguments the function # takes), as well as if
|
||||||
it is an operator. class PrototypeNode(object):
|
it is an operator. class PrototypeNode(object):
|
||||||
|
|
@ -454,7 +454,7 @@ denser the character:
|
||||||
for the number of iterations it takes a function in the complex plane to
|
for the number of iterations it takes a function in the complex plane to
|
||||||
converge:
|
converge:
|
||||||
|
|
||||||
{% highlight python %} # determine whether the specific location
|
# determine whether the specific location
|
||||||
diverges. # Solve for z = z^2 + c in the complex plane. def
|
diverges. # Solve for z = z^2 + c in the complex plane. def
|
||||||
mandelconverger(real imag iters creal cimag) if iters > 255 \|
|
mandelconverger(real imag iters creal cimag) if iters > 255 \|
|
||||||
(real\ *real + imag*\ imag > 4) then iters else
|
(real\ *real + imag*\ imag > 4) then iters else
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ using a PHI node:
|
||||||
into SSA registers, inserting Phi nodes as appropriate. If you run this
|
into SSA registers, inserting Phi nodes as appropriate. If you run this
|
||||||
example through the pass, for example, you'll get:
|
example through the pass, for example, you'll get:
|
||||||
|
|
||||||
{% highlight bash %} $ llvm-as < example.ll \| opt -mem2reg \| llvm-dis
|
$ llvm-as < example.ll \| opt -mem2reg \| llvm-dis
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -358,7 +358,7 @@ from the stack slot:
|
||||||
with ``ForExpressionNode.CodeGen`` (see the `full code listing <#code>`_
|
with ``ForExpressionNode.CodeGen`` (see the `full code listing <#code>`_
|
||||||
for the unabridged code):
|
for the unabridged code):
|
||||||
|
|
||||||
{% highlight python %} def CodeGen(self): function =
|
def CodeGen(self): function =
|
||||||
g_llvm_builder.basic_block.function
|
g_llvm_builder.basic_block.function
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
@ -438,7 +438,7 @@ get good codegen once again:
|
||||||
mem2reg optimization runs. For example, this is the before/after code
|
mem2reg optimization runs. For example, this is the before/after code
|
||||||
for our recursive fib function. Before the optimization:
|
for our recursive fib function. Before the optimization:
|
||||||
|
|
||||||
{% highlight llvm %} define double @fib(double %x) { entry: %x1 = alloca
|
define double @fib(double %x) { entry: %x1 = alloca
|
||||||
double store double %x, double\* %x1 %x2 = load double\* %x1 %cmptmp =
|
double store double %x, double\* %x1 %x2 = load double\* %x1 %cmptmp =
|
||||||
fcmp ult double %x2, 3.000000e+00 %booltmp = uitofp i1 %cmptmp to double
|
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
|
%ifcond = fcmp one double %booltmp, 0.000000e+00 br i1 %ifcond, label
|
||||||
|
|
@ -462,7 +462,7 @@ get good codegen once again:
|
||||||
|
|
||||||
Here is the code after the mem2reg pass runs:
|
Here is the code after the mem2reg pass runs:
|
||||||
|
|
||||||
{% highlight llvm %} define double @fib(double %x) { entry: %cmptmp =
|
define double @fib(double %x) { entry: %cmptmp =
|
||||||
fcmp ult double %x, 3.000000e+00 %booltmp = uitofp i1 %cmptmp to double
|
fcmp ult double %x, 3.000000e+00 %booltmp = uitofp i1 %cmptmp to double
|
||||||
%ifcond = fcmp one double %booltmp, 0.000000e+00 br i1 %ifcond, label
|
%ifcond = fcmp one double %booltmp, 0.000000e+00 br i1 %ifcond, label
|
||||||
%then, label %else then: br label %ifcont else: %subtmp = fsub double
|
%then, label %else then: br label %ifcont else: %subtmp = fsub double
|
||||||
|
|
@ -524,7 +524,7 @@ step is to set a precedence:
|
||||||
takes care of all the parsing and AST generation. We just need to
|
takes care of all the parsing and AST generation. We just need to
|
||||||
implement codegen for the assignment operator. This looks like:
|
implement codegen for the assignment operator. This looks like:
|
||||||
|
|
||||||
{% highlight python %} class
|
class
|
||||||
BinaryOperatorExpressionNode(ExpressionNode): ... def CodeGen(self): # A
|
BinaryOperatorExpressionNode(ExpressionNode): ... def CodeGen(self): # A
|
||||||
special case for '=' because we don't want to emit the LHS as an #
|
special case for '=' because we don't want to emit the LHS as an #
|
||||||
expression. if self.operator == '=': # Assignment requires the LHS to be
|
expression. if self.operator == '=': # Assignment requires the LHS to be
|
||||||
|
|
@ -539,7 +539,7 @@ step is to set a precedence:
|
||||||
is invalid to have ``(x+1) = expr`` -- only things like ``x = expr`` are
|
is invalid to have ``(x+1) = expr`` -- only things like ``x = expr`` are
|
||||||
allowed.
|
allowed.
|
||||||
|
|
||||||
{% highlight python %} # Codegen the RHS. value = self.right.CodeGen()
|
# Codegen the RHS. value = self.right.CodeGen()
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue