a = 1 # ref_cnt of a = 1
b = a # ref_cnt of a = 2
c = a + b # ref_cnt of a 2 -> 3 -> 2
sum_function(a) # ref_cnt of a 3
# A very basic HTTP server
require "http/server"
server = HTTP::Server.new do |context|
context.response.content_type = "text/plain"
context.response.print "Hello world, got #{context.request.path}!"
end
puts "Listening on http://127.0.0.1:8080"
server.listen(8080)
token = tokenize(code)
while token is not None:
if token.type == NAME:
if token.value == 'def':
tree = FunctionDef()
next_token = token.next()
token = token.next()
Token(type=NUMBER, value='0')
Token(type=NAME, value='sum')
if next_token.type != NAME:
raise SyntaxError()
AST
std::string AST = "is Tree"
Target Code
Assign(
targets=[
Name(id='AST')
],
value=Str(value="'is Tree'"),
)
b
b, c
mul $t0, b, c
add $t1, $t0, a
ASM
Bin OP
Bin OP + a
* cb
typedef struct {
char *tp_name;
} A;
typedef struct {
char *tp_name;
int value;
float rate;
} B;
unsigned add1(unsigned a, unsigned b) {
return a + b;
}
unsigned add2(unsigned a, unsigned b) {
if (a == 0) return b;
return add2(a - 1, b + 1);
}
%struct.A = type { i8* }
%struct.B = type { i8*, i32, float }
define i32 @add1(i32 %a, i32 %b) {
entry:
%tmp1 = add i32 %a, %b
ret i32 %tmp1
}
define i32 @add2(i32 %a, i32 %b) {
entry:
%tmp1 = icmp eq i32 %a, 0 br i1
%tmp1, label %done, label %recurse
recurse:
%tmp2 = sub i32 %a, 1
%tmp3 = add i32 %b, 1
%tmp4 = call i32 @add2(i32 %tmp2, i32 %tmp3)
ret i32 %tmp4
done:
ret i32 %b
}
from numba import jit
from numpy import arrange
@jit
def sum2d(arr):
M, N = arr.shape
result = 0.0
for i in range(M):
for j in range(N):
result += arr[i,j]
return result
a = arange(9).reshape(3,3)
print(sum2d(a))
from llvmlite import ir
# Create some useful types
double = ir.DoubleType()
fnty = ir.FunctionType(double, (double, double))
# Create an empty module...
module = ir.Module(name=__file__)
# and declare a function named "fpadd" inside it
func = ir.Function(module, fnty, name="fpadd")
# Now implement the function
block = func.append_basic_block(name="entry")
builder = ir.IRBuilder(block) a, b = func.args
result = builder.fadd(a, b, name="res")
builder.ret(result)
# Print the module IR
print(module)
; ModuleID = "examples/ir_fpadd.py"
target triple = "unknown-unknown-unknown"
target datalayout = ""
define double @"fpadd"(double %".1", double %".2")
{
entry:
%"res" = fadd double %".1", %".2"
ret double %"res"
}
from llvmlite import ir
# Create some useful types
double = ir.DoubleType()
fnty = ir.FunctionType(double, (double, double))
# Create an empty module...
module = ir.Module(name=__file__)
# and declare a function named "fpadd" inside it
func = ir.Function(module, fnty, name="fpadd")
# Now implement the function
block = func.append_basic_block(name="entry")
builder = ir.IRBuilder(block) a, b = func.args
result = builder.fadd(a, b, name="res")
builder.ret(result)
# Print the module IR
print(module)
import llvmlite.binding as llvm
llvm.initialize()
llvm.initialize_native_target()
llvm.initialize_native_asmprinter()
def create_execution_engine():
target = llvm.Target.from_default_triple()
target_machine = target.create_target_machine()
backing_mod = llvm.parse_assembly("")
engine = llvm.create_mcjit_compiler(backing_mod, target_machine)
return engine
def compile_ir(engine, llvm_ir):
mod = llvm.parse_assembly(llvm_ir)
mod.verify()
engine.add_module(mod)
engine.finalize_object()
engine.run_static_constructors()
return mod
engine = create_execution_engine()
mod = compile_ir(engine, llvm_ir)
from ctypes import CFUNCTYPE, c_double
func_ptr = engine.get_function_address("fpadd")
cfunc = CFUNCTYPE(c_double, c_double, c_double)(func_ptr)
res = cfunc(1.0, 3.5)