mirror of https://github.com/m-labs/artiq.git
LLVMIRGenerator: allocate less.
This commit is contained in:
parent
b99eae6b3f
commit
22570afbda
|
@ -7,6 +7,16 @@ from pythonparser import ast, diagnostic
|
|||
from llvmlite_artiq import ir as ll
|
||||
from .. import types, builtins, ir
|
||||
|
||||
|
||||
llvoid = ll.VoidType()
|
||||
lli1 = ll.IntType(1)
|
||||
lli8 = ll.IntType(8)
|
||||
lli32 = ll.IntType(32)
|
||||
lldouble = ll.DoubleType()
|
||||
llptr = ll.IntType(8).as_pointer()
|
||||
llemptyptr = ll.LiteralStructType( []).as_pointer()
|
||||
|
||||
|
||||
class LLVMIRGenerator:
|
||||
def __init__(self, engine, module_name, target):
|
||||
self.engine = engine
|
||||
|
@ -26,11 +36,11 @@ class LLVMIRGenerator:
|
|||
return ll.LiteralStructType([self.llty_of_type(eltty) for eltty in typ.elts])
|
||||
elif types.is_rpc_function(typ):
|
||||
if for_return:
|
||||
return ll.VoidType()
|
||||
return llvoid
|
||||
else:
|
||||
return ll.LiteralStructType([])
|
||||
elif types.is_function(typ):
|
||||
envarg = ll.IntType(8).as_pointer()
|
||||
envarg = llptr
|
||||
llty = ll.FunctionType(args=[envarg] +
|
||||
[self.llty_of_type(typ.args[arg])
|
||||
for arg in typ.args] +
|
||||
|
@ -43,27 +53,27 @@ class LLVMIRGenerator:
|
|||
return ll.LiteralStructType([envarg, llty.as_pointer()])
|
||||
elif builtins.is_none(typ):
|
||||
if for_return:
|
||||
return ll.VoidType()
|
||||
return llvoid
|
||||
else:
|
||||
return ll.LiteralStructType([])
|
||||
elif builtins.is_bool(typ):
|
||||
return ll.IntType(1)
|
||||
return lli1
|
||||
elif builtins.is_int(typ):
|
||||
return ll.IntType(builtins.get_int_width(typ))
|
||||
elif builtins.is_float(typ):
|
||||
return ll.DoubleType()
|
||||
return lldouble
|
||||
elif builtins.is_str(typ) or ir.is_exn_typeinfo(typ):
|
||||
return ll.IntType(8).as_pointer()
|
||||
return llptr
|
||||
elif builtins.is_list(typ):
|
||||
lleltty = self.llty_of_type(builtins.get_iterable_elt(typ))
|
||||
return ll.LiteralStructType([ll.IntType(32), lleltty.as_pointer()])
|
||||
return ll.LiteralStructType([lli32, lleltty.as_pointer()])
|
||||
elif builtins.is_range(typ):
|
||||
lleltty = self.llty_of_type(builtins.get_iterable_elt(typ))
|
||||
return ll.LiteralStructType([lleltty, lleltty, lleltty])
|
||||
elif ir.is_basic_block(typ):
|
||||
return ll.IntType(8).as_pointer()
|
||||
return llptr
|
||||
elif ir.is_option(typ):
|
||||
return ll.LiteralStructType([ll.IntType(1), self.llty_of_type(typ.params["inner"])])
|
||||
return ll.LiteralStructType([lli1, self.llty_of_type(typ.params["inner"])])
|
||||
elif ir.is_environment(typ):
|
||||
llty = ll.LiteralStructType([self.llty_of_type(typ.params[name])
|
||||
for name in typ.params])
|
||||
|
@ -117,14 +127,14 @@ class LLVMIRGenerator:
|
|||
|
||||
llconst = self.llmodule.get_global(name)
|
||||
if llconst is None:
|
||||
llstrty = ll.ArrayType(ll.IntType(8), len(as_bytes))
|
||||
llstrty = ll.ArrayType(lli8, len(as_bytes))
|
||||
llconst = ll.GlobalVariable(self.llmodule, llstrty, name)
|
||||
llconst.global_constant = True
|
||||
llconst.initializer = ll.Constant(llstrty, bytearray(as_bytes))
|
||||
llconst.linkage = linkage
|
||||
llconst.unnamed_addr = unnamed_addr
|
||||
|
||||
return llconst.bitcast(ll.IntType(8).as_pointer())
|
||||
return llconst.bitcast(llptr)
|
||||
else:
|
||||
assert False
|
||||
|
||||
|
@ -134,36 +144,36 @@ class LLVMIRGenerator:
|
|||
return llfun
|
||||
|
||||
if name in "llvm.donothing":
|
||||
llty = ll.FunctionType(ll.VoidType(), [])
|
||||
llty = ll.FunctionType(llvoid, [])
|
||||
elif name in "llvm.trap":
|
||||
llty = ll.FunctionType(ll.VoidType(), [])
|
||||
llty = ll.FunctionType(llvoid, [])
|
||||
elif name == "llvm.floor.f64":
|
||||
llty = ll.FunctionType(ll.DoubleType(), [ll.DoubleType()])
|
||||
llty = ll.FunctionType(lldouble, [lldouble])
|
||||
elif name == "llvm.round.f64":
|
||||
llty = ll.FunctionType(ll.DoubleType(), [ll.DoubleType()])
|
||||
llty = ll.FunctionType(lldouble, [lldouble])
|
||||
elif name == "llvm.pow.f64":
|
||||
llty = ll.FunctionType(ll.DoubleType(), [ll.DoubleType(), ll.DoubleType()])
|
||||
llty = ll.FunctionType(lldouble, [lldouble, lldouble])
|
||||
elif name == "llvm.powi.f64":
|
||||
llty = ll.FunctionType(ll.DoubleType(), [ll.DoubleType(), ll.IntType(32)])
|
||||
llty = ll.FunctionType(lldouble, [lldouble, lli32])
|
||||
elif name == "llvm.copysign.f64":
|
||||
llty = ll.FunctionType(ll.DoubleType(), [ll.DoubleType(), ll.DoubleType()])
|
||||
llty = ll.FunctionType(lldouble, [lldouble, lldouble])
|
||||
elif name == "llvm.stacksave":
|
||||
llty = ll.FunctionType(ll.IntType(8).as_pointer(), [])
|
||||
llty = ll.FunctionType(llptr, [])
|
||||
elif name == "llvm.stackrestore":
|
||||
llty = ll.FunctionType(ll.VoidType(), [ll.IntType(8).as_pointer()])
|
||||
llty = ll.FunctionType(llvoid, [llptr])
|
||||
elif name == self.target.print_function:
|
||||
llty = ll.FunctionType(ll.VoidType(), [ll.IntType(8).as_pointer()], var_arg=True)
|
||||
llty = ll.FunctionType(llvoid, [llptr], var_arg=True)
|
||||
elif name == "__artiq_personality":
|
||||
llty = ll.FunctionType(ll.IntType(32), [], var_arg=True)
|
||||
llty = ll.FunctionType(lli32, [], var_arg=True)
|
||||
elif name == "__artiq_raise":
|
||||
llty = ll.FunctionType(ll.VoidType(), [self.llty_of_type(builtins.TException())])
|
||||
llty = ll.FunctionType(llvoid, [self.llty_of_type(builtins.TException())])
|
||||
elif name == "__artiq_reraise":
|
||||
llty = ll.FunctionType(ll.VoidType(), [])
|
||||
llty = ll.FunctionType(llvoid, [])
|
||||
elif name == "send_rpc":
|
||||
llty = ll.FunctionType(ll.VoidType(), [ll.IntType(32), ll.IntType(8).as_pointer()],
|
||||
llty = ll.FunctionType(llvoid, [lli32, llptr],
|
||||
var_arg=True)
|
||||
elif name == "recv_rpc":
|
||||
llty = ll.FunctionType(ll.IntType(32), [ll.IntType(8).as_pointer()])
|
||||
llty = ll.FunctionType(lli32, [llptr])
|
||||
else:
|
||||
assert False
|
||||
|
||||
|
@ -254,7 +264,7 @@ class LLVMIRGenerator:
|
|||
return llinsn
|
||||
|
||||
def llindex(self, index):
|
||||
return ll.Constant(ll.IntType(32), index)
|
||||
return ll.Constant(lli32, index)
|
||||
|
||||
def process_Alloc(self, insn):
|
||||
if ir.is_environment(insn.type):
|
||||
|
@ -263,11 +273,11 @@ class LLVMIRGenerator:
|
|||
elif ir.is_option(insn.type):
|
||||
if len(insn.operands) == 0: # empty
|
||||
llvalue = ll.Constant(self.llty_of_type(insn.type), ll.Undefined)
|
||||
return self.llbuilder.insert_value(llvalue, ll.Constant(ll.IntType(1), False), 0,
|
||||
return self.llbuilder.insert_value(llvalue, ll.Constant(lli1, False), 0,
|
||||
name=insn.name)
|
||||
elif len(insn.operands) == 1: # full
|
||||
llvalue = ll.Constant(self.llty_of_type(insn.type), ll.Undefined)
|
||||
llvalue = self.llbuilder.insert_value(llvalue, ll.Constant(ll.IntType(1), True), 0)
|
||||
llvalue = self.llbuilder.insert_value(llvalue, ll.Constant(lli1, True), 0)
|
||||
return self.llbuilder.insert_value(llvalue, self.map(insn.operands[0]), 1,
|
||||
name=insn.name)
|
||||
else:
|
||||
|
@ -439,8 +449,8 @@ class LLVMIRGenerator:
|
|||
[self.map(insn.lhs()), self.map(insn.rhs())],
|
||||
name=insn.name)
|
||||
else:
|
||||
lllhs = self.llbuilder.sitofp(self.map(insn.lhs()), ll.DoubleType())
|
||||
llrhs = self.llbuilder.trunc(self.map(insn.rhs()), ll.IntType(32))
|
||||
lllhs = self.llbuilder.sitofp(self.map(insn.lhs()), lldouble)
|
||||
llrhs = self.llbuilder.trunc(self.map(insn.rhs()), lli32)
|
||||
llvalue = self.llbuilder.call(self.llbuiltin("llvm.powi.f64"), [lllhs, llrhs])
|
||||
return self.llbuilder.fptosi(llvalue, self.llty_of_type(insn.type),
|
||||
name=insn.name)
|
||||
|
@ -497,19 +507,19 @@ class LLVMIRGenerator:
|
|||
elif isinstance(lllhs.type, ll.PointerType):
|
||||
return self.llbuilder.icmp_unsigned(op, lllhs, llrhs,
|
||||
name=insn.name)
|
||||
elif isinstance(lllhs.type, (ll.FloatType, ll.DoubleType)):
|
||||
elif isinstance(lllhs.type, ll.DoubleType):
|
||||
return self.llbuilder.fcmp_ordered(op, lllhs, llrhs,
|
||||
name=insn.name)
|
||||
elif isinstance(lllhs.type, ll.LiteralStructType):
|
||||
# Compare aggregates (such as lists or ranges) element-by-element.
|
||||
llvalue = ll.Constant(ll.IntType(1), True)
|
||||
llvalue = ll.Constant(lli1, True)
|
||||
for index in range(len(lllhs.type.elements)):
|
||||
lllhselt = self.llbuilder.extract_value(lllhs, index)
|
||||
llrhselt = self.llbuilder.extract_value(llrhs, index)
|
||||
llresult = self.llbuilder.icmp_unsigned('==', lllhselt, llrhselt)
|
||||
llvalue = self.llbuilder.select(llresult, llvalue,
|
||||
ll.Constant(ll.IntType(1), False))
|
||||
return self.llbuilder.icmp_unsigned(op, llvalue, ll.Constant(ll.IntType(1), True),
|
||||
ll.Constant(lli1, False))
|
||||
return self.llbuilder.icmp_unsigned(op, llvalue, ll.Constant(lli1, True),
|
||||
name=insn.name)
|
||||
else:
|
||||
print(lllhs, llrhs)
|
||||
|
@ -567,7 +577,7 @@ class LLVMIRGenerator:
|
|||
|
||||
def process_Closure(self, insn):
|
||||
llvalue = ll.Constant(self.llty_of_type(insn.target_function.type), ll.Undefined)
|
||||
llenv = self.llbuilder.bitcast(self.map(insn.environment()), ll.IntType(8).as_pointer())
|
||||
llenv = self.llbuilder.bitcast(self.map(insn.environment()), llptr)
|
||||
llvalue = self.llbuilder.insert_value(llvalue, llenv, 0)
|
||||
llvalue = self.llbuilder.insert_value(llvalue, self.map(insn.target_function), 1,
|
||||
name=insn.name)
|
||||
|
@ -611,7 +621,7 @@ class LLVMIRGenerator:
|
|||
error_handler(typ)
|
||||
|
||||
def _build_rpc(self, fun_loc, fun_type, args, llnormalblock, llunwindblock):
|
||||
llservice = ll.Constant(ll.IntType(32), fun_type.service)
|
||||
llservice = ll.Constant(lli32, fun_type.service)
|
||||
|
||||
tag = b""
|
||||
|
||||
|
@ -676,7 +686,7 @@ class LLVMIRGenerator:
|
|||
|
||||
llretty = self.llty_of_type(fun_type.ret)
|
||||
llslot = self.llbuilder.alloca(llretty)
|
||||
llslotgen = self.llbuilder.bitcast(llslot, ll.IntType(8).as_pointer())
|
||||
llslotgen = self.llbuilder.bitcast(llslot, llptr)
|
||||
self.llbuilder.branch(llhead)
|
||||
|
||||
self.llbuilder.position_at_end(llhead)
|
||||
|
@ -692,7 +702,7 @@ class LLVMIRGenerator:
|
|||
self.llbuilder.cbranch(lldone, lltail, llalloc)
|
||||
|
||||
self.llbuilder.position_at_end(llalloc)
|
||||
llalloca = self.llbuilder.alloca(ll.IntType(8), llsize)
|
||||
llalloca = self.llbuilder.alloca(lli8, llsize)
|
||||
llphi.add_incoming(llalloca, llalloc)
|
||||
self.llbuilder.branch(llhead)
|
||||
|
||||
|
@ -783,8 +793,8 @@ class LLVMIRGenerator:
|
|||
|
||||
def process_LandingPad(self, insn):
|
||||
# Layout on return from landing pad: {%_Unwind_Exception*, %Exception*}
|
||||
lllandingpadty = ll.LiteralStructType([ll.IntType(8).as_pointer(),
|
||||
ll.IntType(8).as_pointer()])
|
||||
lllandingpadty = ll.LiteralStructType([llptr,
|
||||
llptr])
|
||||
lllandingpad = self.llbuilder.landingpad(lllandingpadty,
|
||||
self.llbuiltin("__artiq_personality"),
|
||||
cleanup=True)
|
||||
|
|
Loading…
Reference in New Issue