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