Skip to content

Commit

Permalink
switch to llvmlite
Browse files Browse the repository at this point in the history
sbourdeauducq committed Dec 5, 2014
1 parent b93b969 commit 159f632
Showing 16 changed files with 258 additions and 303 deletions.
90 changes: 45 additions & 45 deletions artiq/coredevice/runtime.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import os
from fractions import Fraction

from llvm import core as lc
from llvm import target as lt
import llvmlite.ir as ll
import llvmlite.binding as llvm

from artiq.py2llvm import base_types
from artiq.language import units


lt.initialize_all()
llvm.initialize()
llvm.initialize_all_targets()
llvm.initialize_all_asmprinters()

_syscalls = {
"rpc": "i+:i",
@@ -23,10 +24,10 @@
}

_chr_to_type = {
"n": lambda: lc.Type.void(),
"b": lambda: lc.Type.int(1),
"i": lambda: lc.Type.int(32),
"I": lambda: lc.Type.int(64)
"n": lambda: ll.VoidType(),
"b": lambda: ll.IntType(1),
"i": lambda: ll.IntType(32),
"I": lambda: ll.IntType(64)
}

_chr_to_value = {
@@ -45,45 +46,50 @@ def _str_to_functype(s):
type_args = []
for n, c in enumerate(s[:-2]):
if c == "+":
type_args.append(lc.Type.int())
type_args.append(ll.IntType(32))
var_arg_fixcount = n
elif c != "n":
type_args.append(_chr_to_type[c]())
return (var_arg_fixcount,
lc.Type.function(type_ret, type_args,
var_arg=var_arg_fixcount is not None))
ll.FunctionType(type_ret, type_args,
var_arg=var_arg_fixcount is not None))


class LinkInterface:
def init_module(self, module):
self.llvm_module = module.llvm_module
self.module = module
llvm_module = self.module.llvm_module

# syscalls
self.syscalls = dict()
self.var_arg_fixcount = dict()
for func_name, func_type_str in _syscalls.items():
var_arg_fixcount, func_type = _str_to_functype(func_type_str)
if var_arg_fixcount is not None:
self.var_arg_fixcount[func_name] = var_arg_fixcount
self.llvm_module.add_function(func_type, "__syscall_"+func_name)
self.syscalls[func_name] = ll.Function(
llvm_module, func_type, "__syscall_" + func_name)

# exception handling
func_type = lc.Type.function(lc.Type.int(), [lc.Type.pointer(lc.Type.int(8))])
function = self.llvm_module.add_function(func_type, "__eh_setjmp")
function.add_attribute(lc.ATTR_NO_UNWIND)
function.add_attribute(lc.ATTR_RETURNS_TWICE)
func_type = ll.FunctionType(ll.IntType(32),
[ll.PointerType(ll.IntType(8))])
self.eh_setjmp = ll.Function(llvm_module, func_type,
"__eh_setjmp")
self.eh_setjmp.attributes.add("nounwind")
self.eh_setjmp.attributes.add("returns_twice")

func_type = lc.Type.function(lc.Type.pointer(lc.Type.int(8)), [])
self.llvm_module.add_function(func_type, "__eh_push")
func_type = ll.FunctionType(ll.PointerType(ll.IntType(8)), [])
self.eh_push = ll.Function(llvm_module, func_type, "__eh_push")

func_type = lc.Type.function(lc.Type.void(), [lc.Type.int()])
self.llvm_module.add_function(func_type, "__eh_pop")
func_type = ll.FunctionType(ll.VoidType(), [ll.IntType(32)])
self.eh_pop = ll.Function(llvm_module, func_type, "__eh_pop")

func_type = lc.Type.function(lc.Type.int(), [])
self.llvm_module.add_function(func_type, "__eh_getid")
func_type = ll.FunctionType(ll.IntType(32), [])
self.eh_getid = ll.Function(llvm_module, func_type, "__eh_getid")

func_type = lc.Type.function(lc.Type.void(), [lc.Type.int()])
function = self.llvm_module.add_function(func_type, "__eh_raise")
function.add_attribute(lc.ATTR_NO_RETURN)
func_type = ll.FunctionType(ll.VoidType(), [ll.IntType(32)])
self.eh_raise = ll.Function(llvm_module, func_type, "__eh_raise")
self.eh_raise.attributes.add("noreturn")

def build_syscall(self, syscall_name, args, builder):
r = _chr_to_value[_syscalls[syscall_name][-1]]()
@@ -92,33 +98,27 @@ def build_syscall(self, syscall_name, args, builder):
if syscall_name in self.var_arg_fixcount:
fixcount = self.var_arg_fixcount[syscall_name]
args = args[:fixcount] \
+ [lc.Constant.int(lc.Type.int(), len(args) - fixcount)] \
+ [ll.Constant(ll.IntType(32), len(args) - fixcount)] \
+ args[fixcount:]
llvm_function = self.llvm_module.get_function_named(
"__syscall_" + syscall_name)
r.auto_store(builder, builder.call(llvm_function, args))
r.auto_store(builder, builder.call(self.syscalls[syscall_name],
args))
return r

def build_catch(self, builder):
eh_setjmp = self.llvm_module.get_function_named("__eh_setjmp")
eh_push = self.llvm_module.get_function_named("__eh_push")
jmpbuf = builder.call(eh_push, [])
exception_occured = builder.call(eh_setjmp, [jmpbuf])
return builder.icmp(lc.ICMP_NE,
exception_occured,
lc.Constant.int(lc.Type.int(), 0))
jmpbuf = builder.call(self.eh_push, [])
exception_occured = builder.call(self.eh_setjmp, [jmpbuf])
return builder.icmp_signed("!=",
exception_occured,
ll.Constant(ll.IntType(32), 0))

def build_pop(self, builder, levels):
eh_pop = self.llvm_module.get_function_named("__eh_pop")
builder.call(eh_pop, [lc.Constant.int(lc.Type.int(), levels)])
builder.call(self.eh_pop, [ll.Constant(ll.IntType(32), levels)])

def build_getid(self, builder):
eh_getid = self.llvm_module.get_function_named("__eh_getid")
return builder.call(eh_getid, [])
return builder.call(self.eh_getid, [])

def build_raise(self, builder, eid):
eh_raise = self.llvm_module.get_function_named("__eh_raise")
builder.call(eh_raise, [eid])
builder.call(self.eh_raise, [eid])


def _debug_dump_obj(obj):
@@ -148,8 +148,8 @@ def __init__(self, internal_ref_period):
self.warmup_time = 1*units.ms

def emit_object(self):
tm = lt.TargetMachine.new(triple=self.cpu_type, cpu="generic")
obj = tm.emit_object(self.llvm_module)
tm = llvm.Target.from_triple(self.cpu_type).create_target_machine()
obj = tm.emit_object(self.module.llvm_module)
_debug_dump_obj(obj)
return obj

16 changes: 8 additions & 8 deletions artiq/py2llvm/arrays.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from llvm import core as lc
import llvmlite.ir as ll

from artiq.py2llvm.values import VGeneric
from artiq.py2llvm.base_types import VInt
@@ -13,7 +13,7 @@ def __init__(self, el_init, count):
raise TypeError("Arrays must have at least one element")

def get_llvm_type(self):
return lc.Type.array(self.el_init.get_llvm_type(), self.count)
return ll.ArrayType(self.el_init.get_llvm_type(), self.count)

def __repr__(self):
return "<VArray:{} x{}>".format(repr(self.el_init), self.count)
@@ -42,7 +42,7 @@ def set_value(self, builder, v):

i = VInt()
i.alloca(builder, "ai_i")
i.auto_store(builder, lc.Constant.int(lc.Type.int(), 0))
i.auto_store(builder, ll.Constant(ll.IntType(32), 0))

function = builder.basic_block.function
copy_block = function.append_basic_block("ai_copy")
@@ -52,10 +52,10 @@ def set_value(self, builder, v):
builder.position_at_end(copy_block)
self.o_subscript(i, builder).set_value(builder, v.el_init)
i.auto_store(builder, builder.add(
i.auto_load(builder), lc.Constant.int(lc.Type.int(), 1)))
cont = builder.icmp(
lc.ICMP_SLT, i.auto_load(builder),
lc.Constant.int(lc.Type.int(), self.count))
i.auto_load(builder), ll.Constant(ll.IntType(32), 1)))
cont = builder.icmp_signed(
"<", i.auto_load(builder),
ll.Constant(ll.IntType(32), self.count))
builder.cbranch(cont, copy_block, end_block)

builder.position_at_end(end_block)
@@ -65,6 +65,6 @@ def o_subscript(self, index, builder):
if builder is not None:
index = index.o_int(builder).auto_load(builder)
ssa_r = builder.gep(self.llvm_value, [
lc.Constant.int(lc.Type.int(), 0), index])
ll.Constant(ll.IntType(32), 0), index])
r.auto_store(builder, ssa_r)
return r
39 changes: 20 additions & 19 deletions artiq/py2llvm/ast_body.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import ast
from llvm import core as lc

import llvmlite.ir as ll

from artiq.py2llvm import values, base_types, fractions, arrays, iterators
from artiq.py2llvm.tools import is_terminated
@@ -368,21 +369,21 @@ def _visit_stmt_Raise(self, node):
if self._active_exception_stack:
finally_block, propagate, propagate_eid = (
self._active_exception_stack[-1])
self.builder.store(lc.Constant.int(lc.Type.int(1), 1), propagate)
self.builder.store(ll.Constant(ll.IntType(1), 1), propagate)
if node.exc is not None:
eid = lc.Constant.int(lc.Type.int(), node.exc.args[0].n)
eid = ll.Constant(ll.IntType(32), node.exc.args[0].n)
self.builder.store(eid, propagate_eid)
self.builder.branch(finally_block)
else:
eid = lc.Constant.int(lc.Type.int(), node.exc.args[0].n)
eid = ll.Constant(ll.IntType(32), node.exc.args[0].n)
self.env.build_raise(self.builder, eid)

def _handle_exception(self, function, finally_block,
propagate, propagate_eid, handlers):
eid = self.env.build_getid(self.builder)
self._active_exception_stack.append(
(finally_block, propagate, propagate_eid))
self.builder.store(lc.Constant.int(lc.Type.int(1), 1), propagate)
self.builder.store(ll.Constant(ll.IntType(1), 1), propagate)
self.builder.store(eid, propagate_eid)

for handler in handlers:
@@ -392,23 +393,23 @@ def _handle_exception(self, function, finally_block,
self.builder.branch(handled_exc_block)
else:
if isinstance(handler.type, ast.Tuple):
match = self.builder.icmp(
lc.ICMP_EQ, eid,
lc.Constant.int(lc.Type.int(),
handler.type.elts[0].args[0].n))
match = self.builder.icmp_signed(
"==", eid,
ll.Constant(ll.IntType(32),
handler.type.elts[0].args[0].n))
for elt in handler.type.elts[1:]:
match = self.builder.or_(
match,
self.builder.icmp(
lc.ICMP_EQ, eid,
lc.Constant.int(lc.Type.int(), elt.args[0].n)))
self.builder.icmp_signed(
"==", eid,
ll.Constant(ll.IntType(32), elt.args[0].n)))
else:
match = self.builder.icmp(
lc.ICMP_EQ, eid,
lc.Constant.int(lc.Type.int(), handler.type.args[0].n))
match = self.builder.icmp_signed(
"==", eid,
ll.Constant(ll.IntType(32), handler.type.args[0].n))
self.builder.cbranch(match, handled_exc_block, cont_exc_block)
self.builder.position_at_end(handled_exc_block)
self.builder.store(lc.Constant.int(lc.Type.int(1), 0), propagate)
self.builder.store(ll.Constant(ll.IntType(1), 0), propagate)
self.visit_statements(handler.body)
if not self._bb_terminated():
self.builder.branch(finally_block)
@@ -423,10 +424,10 @@ def _visit_stmt_Try(self, node):
exc_block = function.append_basic_block("try_exc")
finally_block = function.append_basic_block("try_finally")

propagate = self.builder.alloca(lc.Type.int(1),
propagate = self.builder.alloca(ll.IntType(1),
name="propagate")
self.builder.store(lc.Constant.int(lc.Type.int(1), 0), propagate)
propagate_eid = self.builder.alloca(lc.Type.int(),
self.builder.store(ll.Constant(ll.IntType(1), 0), propagate)
propagate_eid = self.builder.alloca(ll.IntType(32),
name="propagate_eid")
exception_occured = self.env.build_catch(self.builder)
self.builder.cbranch(exception_occured, exc_block, noexc_block)
Loading

0 comments on commit 159f632

Please sign in to comment.