mirror of https://github.com/m-labs/artiq.git
61 lines
2.0 KiB
Python
61 lines
2.0 KiB
Python
from llvm import core as lc
|
|
from llvm import passes as lp
|
|
from llvm import ee as le
|
|
|
|
from artiq.py2llvm import infer_types, ast_body, base_types, fractions, tools
|
|
|
|
|
|
class Module:
|
|
def __init__(self, env=None):
|
|
self.llvm_module = lc.Module.new("main")
|
|
self.env = env
|
|
|
|
if self.env is not None:
|
|
self.env.init_module(self)
|
|
fractions.init_module(self)
|
|
|
|
def finalize(self):
|
|
pass_manager = lp.PassManager.new()
|
|
pass_manager.add(lp.PASS_MEM2REG)
|
|
pass_manager.add(lp.PASS_INSTCOMBINE)
|
|
pass_manager.add(lp.PASS_REASSOCIATE)
|
|
pass_manager.add(lp.PASS_GVN)
|
|
pass_manager.add(lp.PASS_SIMPLIFYCFG)
|
|
pass_manager.run(self.llvm_module)
|
|
|
|
def get_ee(self):
|
|
self.finalize()
|
|
return le.ExecutionEngine.new(self.llvm_module)
|
|
|
|
def emit_object(self):
|
|
self.finalize()
|
|
return self.env.emit_object()
|
|
|
|
def compile_function(self, func_def, param_types):
|
|
ns = infer_types.infer_function_types(self.env, func_def, param_types)
|
|
retval = ns["return"]
|
|
|
|
function_type = lc.Type.function(retval.get_llvm_type(),
|
|
[ns[arg.arg].get_llvm_type() for arg in func_def.args.args])
|
|
function = self.llvm_module.add_function(function_type, func_def.name)
|
|
bb = function.append_basic_block("entry")
|
|
builder = lc.Builder.new(bb)
|
|
|
|
for arg_ast, arg_llvm in zip(func_def.args.args, function.args):
|
|
arg_llvm.name = arg_ast.arg
|
|
for k, v in ns.items():
|
|
v.alloca(builder, k)
|
|
for arg_ast, arg_llvm in zip(func_def.args.args, function.args):
|
|
ns[arg_ast.arg].auto_store(builder, arg_llvm)
|
|
|
|
visitor = ast_body.Visitor(self.env, ns, builder)
|
|
visitor.visit_statements(func_def.body)
|
|
|
|
if not tools.is_terminated(builder.basic_block):
|
|
if isinstance(retval, base_types.VNone):
|
|
builder.ret_void()
|
|
else:
|
|
builder.ret(retval.auto_load(builder))
|
|
|
|
return function, retval
|