forked from M-Labs/artiq
compiler: significantly increase readability of LLVM and ARTIQ IRs.
This commit is contained in:
parent
8d0566661a
commit
3ee9834197
|
@ -437,7 +437,7 @@ class Function:
|
|||
|
||||
def _add_name(self, base_name):
|
||||
if base_name == "":
|
||||
name = "v.{}".format(self.next_name)
|
||||
name = "UNN.{}".format(self.next_name)
|
||||
self.next_name += 1
|
||||
elif base_name in self.names:
|
||||
name = "{}.{}".format(base_name, self.next_name)
|
||||
|
@ -869,9 +869,11 @@ class Builtin(Instruction):
|
|||
"""
|
||||
:param op: (string) operation name
|
||||
"""
|
||||
def __init__(self, op, operands, typ, name=""):
|
||||
def __init__(self, op, operands, typ, name=None):
|
||||
assert isinstance(op, str)
|
||||
for operand in operands: assert isinstance(operand, Value)
|
||||
if name is None:
|
||||
name = "BLT.{}".format(op)
|
||||
super().__init__(operands, typ, name)
|
||||
self.op = op
|
||||
|
||||
|
|
|
@ -237,25 +237,25 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
for arg_name, default_node in zip(typ.optargs, node.args.defaults):
|
||||
default = self.visit(default_node)
|
||||
env_default_name = \
|
||||
self.current_env.type.add("default$" + arg_name, default.type)
|
||||
self.current_env.type.add("$default." + arg_name, default.type)
|
||||
self.append(ir.SetLocal(self.current_env, env_default_name, default))
|
||||
defaults.append(env_default_name)
|
||||
|
||||
old_name, self.name = self.name, self.name + [name]
|
||||
|
||||
env_arg = ir.EnvironmentArgument(self.current_env.type, "outerenv")
|
||||
env_arg = ir.EnvironmentArgument(self.current_env.type, "CLS")
|
||||
|
||||
old_args, self.current_args = self.current_args, {}
|
||||
|
||||
args = []
|
||||
for arg_name in typ.args:
|
||||
arg = ir.Argument(typ.args[arg_name], "arg." + arg_name)
|
||||
arg = ir.Argument(typ.args[arg_name], "ARG." + arg_name)
|
||||
self.current_args[arg_name] = arg
|
||||
args.append(arg)
|
||||
|
||||
optargs = []
|
||||
for arg_name in typ.optargs:
|
||||
arg = ir.Argument(ir.TOption(typ.optargs[arg_name]), "arg." + arg_name)
|
||||
arg = ir.Argument(ir.TOption(typ.optargs[arg_name]), "ARG." + arg_name)
|
||||
self.current_args[arg_name] = arg
|
||||
optargs.append(arg)
|
||||
|
||||
|
@ -268,7 +268,7 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
if not is_lambda:
|
||||
self.function_map[node] = func
|
||||
|
||||
entry = self.add_block()
|
||||
entry = self.add_block("entry")
|
||||
old_block, self.current_block = self.current_block, entry
|
||||
|
||||
old_globals, self.current_globals = self.current_globals, node.globals_in_scope
|
||||
|
@ -279,13 +279,13 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
if var not in node.globals_in_scope}
|
||||
env_type = ir.TEnvironment(name=func.name,
|
||||
vars=env_without_globals, outer=self.current_env.type)
|
||||
env = self.append(ir.Alloc([], env_type, name="env"))
|
||||
env = self.append(ir.Alloc([], env_type, name="ENV"))
|
||||
old_env, self.current_env = self.current_env, env
|
||||
|
||||
if not is_lambda:
|
||||
priv_env_type = ir.TEnvironment(name=func.name + ".priv",
|
||||
priv_env_type = ir.TEnvironment(name="{}.private".format(func.name),
|
||||
vars={ "$return": typ.ret })
|
||||
priv_env = self.append(ir.Alloc([], priv_env_type, name="privenv"))
|
||||
priv_env = self.append(ir.Alloc([], priv_env_type, name="PRV"))
|
||||
old_priv_env, self.current_private_env = self.current_private_env, priv_env
|
||||
|
||||
self.append(ir.SetLocal(env, "$outer", env_arg))
|
||||
|
@ -401,18 +401,18 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
cond = self.coerce_to_bool(cond)
|
||||
head = self.current_block
|
||||
|
||||
if_true = self.add_block()
|
||||
if_true = self.add_block("if.body")
|
||||
self.current_block = if_true
|
||||
self.visit(node.body)
|
||||
post_if_true = self.current_block
|
||||
|
||||
if any(node.orelse):
|
||||
if_false = self.add_block()
|
||||
if_false = self.add_block("if.else")
|
||||
self.current_block = if_false
|
||||
self.visit(node.orelse)
|
||||
post_if_false = self.current_block
|
||||
|
||||
tail = self.add_block()
|
||||
tail = self.add_block("if.tail")
|
||||
self.current_block = tail
|
||||
if not post_if_true.is_terminated():
|
||||
post_if_true.append(ir.Branch(tail))
|
||||
|
@ -499,9 +499,9 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
head = self.add_block("for.head")
|
||||
self.append(ir.Branch(head))
|
||||
self.current_block = head
|
||||
phi = self.append(ir.Phi(length.type))
|
||||
phi = self.append(ir.Phi(length.type, name="IND"))
|
||||
phi.add_incoming(ir.Constant(0, phi.type), prehead)
|
||||
cond = self.append(ir.Compare(ast.Lt(loc=None), phi, length))
|
||||
cond = self.append(ir.Compare(ast.Lt(loc=None), phi, length, name="CMP"))
|
||||
|
||||
break_block = self.add_block("for.break")
|
||||
old_break, self.break_target = self.break_target, break_block
|
||||
|
@ -510,7 +510,8 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
old_continue, self.continue_target = self.continue_target, continue_block
|
||||
self.current_block = continue_block
|
||||
|
||||
updated_index = self.append(ir.Arith(ast.Add(loc=None), phi, ir.Constant(1, phi.type)))
|
||||
updated_index = self.append(ir.Arith(ast.Add(loc=None), phi, ir.Constant(1, phi.type),
|
||||
name="IND.new"))
|
||||
phi.add_incoming(updated_index, continue_block)
|
||||
self.append(ir.Branch(head))
|
||||
|
||||
|
@ -597,13 +598,13 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
# k for continuation
|
||||
final_suffix = ".try@{}:{}".format(node.loc.line(), node.loc.column())
|
||||
final_env_type = ir.TEnvironment(name=self.current_function.name + final_suffix,
|
||||
vars={ "$k": ir.TBasicBlock() })
|
||||
vars={ "$cont": ir.TBasicBlock() })
|
||||
final_state = self.append(ir.Alloc([], final_env_type))
|
||||
final_targets = []
|
||||
final_paths = []
|
||||
|
||||
def final_branch(target, block):
|
||||
block.append(ir.SetLocal(final_state, "$k", target))
|
||||
block.append(ir.SetLocal(final_state, "$cont", target))
|
||||
final_targets.append(target)
|
||||
final_paths.append(block)
|
||||
|
||||
|
@ -696,19 +697,19 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
block.append(ir.Branch(finalizer))
|
||||
|
||||
if not body.is_terminated():
|
||||
body.append(ir.SetLocal(final_state, "$k", tail))
|
||||
body.append(ir.SetLocal(final_state, "$cont", tail))
|
||||
body.append(ir.Branch(finalizer))
|
||||
|
||||
cleanup.append(ir.SetLocal(final_state, "$k", reraise))
|
||||
cleanup.append(ir.SetLocal(final_state, "$cont", reraise))
|
||||
cleanup.append(ir.Branch(finalizer))
|
||||
|
||||
for handler, post_handler in handlers:
|
||||
if not post_handler.is_terminated():
|
||||
post_handler.append(ir.SetLocal(final_state, "$k", tail))
|
||||
post_handler.append(ir.SetLocal(final_state, "$cont", tail))
|
||||
post_handler.append(ir.Branch(finalizer))
|
||||
|
||||
if not post_finalizer.is_terminated():
|
||||
dest = post_finalizer.append(ir.GetLocal(final_state, "$k"))
|
||||
dest = post_finalizer.append(ir.GetLocal(final_state, "$cont"))
|
||||
post_finalizer.append(ir.IndirectBranch(dest, final_targets))
|
||||
else:
|
||||
if not body.is_terminated():
|
||||
|
@ -753,7 +754,7 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
|
||||
heads, tails = [], []
|
||||
for stmt in node.body:
|
||||
self.current_block = self.add_block()
|
||||
self.current_block = self.add_block("interleave.branch")
|
||||
heads.append(self.current_block)
|
||||
self.visit(stmt)
|
||||
tails.append(self.current_block)
|
||||
|
@ -761,7 +762,7 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
for head in heads:
|
||||
interleave.add_destination(head)
|
||||
|
||||
self.current_block = self.add_block()
|
||||
self.current_block = self.add_block("interleave.tail")
|
||||
for tail in tails:
|
||||
if not tail.is_terminated():
|
||||
tail.append(ir.Branch(self.current_block))
|
||||
|
@ -773,7 +774,7 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
for stmt in node.body:
|
||||
self.append(ir.Builtin("at_mu", [start_mu], builtins.TNone()))
|
||||
|
||||
block = self.add_block()
|
||||
block = self.add_block("parallel.branch")
|
||||
if self.current_block.is_terminated():
|
||||
self.warn_unreachable(stmt[0])
|
||||
else:
|
||||
|
@ -837,17 +838,17 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
cond = self.visit(node.test)
|
||||
head = self.current_block
|
||||
|
||||
if_true = self.add_block()
|
||||
if_true = self.add_block("ifexp.body")
|
||||
self.current_block = if_true
|
||||
true_result = self.visit(node.body)
|
||||
post_if_true = self.current_block
|
||||
|
||||
if_false = self.add_block()
|
||||
if_false = self.add_block("ifexp.else")
|
||||
self.current_block = if_false
|
||||
false_result = self.visit(node.orelse)
|
||||
post_if_false = self.current_block
|
||||
|
||||
tail = self.add_block()
|
||||
tail = self.add_block("ifexp.tail")
|
||||
self.current_block = tail
|
||||
|
||||
if not post_if_true.is_terminated():
|
||||
|
@ -881,10 +882,10 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
if self.current_class is not None and \
|
||||
name in self.current_class.type.attributes:
|
||||
return self.append(ir.GetAttr(self.current_class, name,
|
||||
name="local." + name))
|
||||
name="FLD." + name))
|
||||
|
||||
return self.append(ir.GetLocal(self._env_for(name), name,
|
||||
name="local." + name))
|
||||
name="LOC." + name))
|
||||
|
||||
def _set_local(self, name, value):
|
||||
if self.current_class is not None and \
|
||||
|
@ -910,7 +911,7 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
|
||||
if self.current_assign is None:
|
||||
return self.append(ir.GetAttr(obj, node.attr,
|
||||
name="{}.{}".format(_readable_name(obj), node.attr)))
|
||||
name="{}.FLD.{}".format(_readable_name(obj), node.attr)))
|
||||
elif types.is_rpc_function(self.current_assign.type):
|
||||
# RPC functions are just type-level markers
|
||||
return self.append(ir.Builtin("nop", [], builtins.TNone()))
|
||||
|
@ -930,47 +931,47 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
ir.Constant(False, builtins.TBool())))
|
||||
head = self.current_block
|
||||
|
||||
self.current_block = out_of_bounds_block = self.add_block()
|
||||
self.current_block = out_of_bounds_block = self.add_block("index.outofbounds")
|
||||
exn = self.alloc_exn(builtins.TException("IndexError"),
|
||||
ir.Constant("index {0} out of bounds 0:{1}", builtins.TStr()),
|
||||
index, length)
|
||||
self.raise_exn(exn, loc=loc)
|
||||
|
||||
self.current_block = in_bounds_block = self.add_block()
|
||||
self.current_block = in_bounds_block = self.add_block("index.inbounds")
|
||||
head.append(ir.BranchIf(in_bounds, in_bounds_block, out_of_bounds_block))
|
||||
|
||||
return mapped_index
|
||||
|
||||
def _make_check(self, cond, exn_gen, loc=None):
|
||||
def _make_check(self, cond, exn_gen, loc=None, name="check"):
|
||||
# cond: bool Value, condition
|
||||
# exn_gen: lambda()->exn Value, exception if condition not true
|
||||
cond_block = self.current_block
|
||||
|
||||
self.current_block = body_block = self.add_block()
|
||||
self.current_block = body_block = self.add_block("{}.body".format(name))
|
||||
self.raise_exn(exn_gen(), loc=loc)
|
||||
|
||||
self.current_block = tail_block = self.add_block()
|
||||
self.current_block = tail_block = self.add_block("{}.tail".format(name))
|
||||
cond_block.append(ir.BranchIf(cond, tail_block, body_block))
|
||||
|
||||
def _make_loop(self, init, cond_gen, body_gen):
|
||||
def _make_loop(self, init, cond_gen, body_gen, name="loop"):
|
||||
# init: 'iter Value, initial loop variable value
|
||||
# cond_gen: lambda('iter Value)->bool Value, loop condition
|
||||
# body_gen: lambda('iter Value)->'iter Value, loop body,
|
||||
# returns next loop variable value
|
||||
init_block = self.current_block
|
||||
|
||||
self.current_block = head_block = self.add_block()
|
||||
self.current_block = head_block = self.add_block("{}.head".format(name))
|
||||
init_block.append(ir.Branch(head_block))
|
||||
phi = self.append(ir.Phi(init.type))
|
||||
phi.add_incoming(init, init_block)
|
||||
cond = cond_gen(phi)
|
||||
|
||||
self.current_block = body_block = self.add_block()
|
||||
self.current_block = body_block = self.add_block("{}.body".format(name))
|
||||
body = body_gen(phi)
|
||||
self.append(ir.Branch(head_block))
|
||||
phi.add_incoming(body, self.current_block)
|
||||
|
||||
self.current_block = tail_block = self.add_block()
|
||||
self.current_block = tail_block = self.add_block("{}.tail".format(name))
|
||||
head_block.append(ir.BranchIf(cond, body_block, tail_block))
|
||||
|
||||
return head_block, body_block, tail_block
|
||||
|
@ -1072,7 +1073,7 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
|
||||
prehead = self.current_block
|
||||
|
||||
head = self.current_block = self.add_block()
|
||||
head = self.current_block = self.add_block("slice.head")
|
||||
prehead.append(ir.Branch(head))
|
||||
|
||||
index = self.append(ir.Phi(node.slice.type,
|
||||
|
@ -1087,7 +1088,7 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
bounded_down = self.append(ir.Compare(ast.Gt(loc=None), index, mapped_stop_index))
|
||||
within_bounds = self.append(ir.Select(counting_up, bounded_up, bounded_down))
|
||||
|
||||
body = self.current_block = self.add_block()
|
||||
body = self.current_block = self.add_block("slice.body")
|
||||
|
||||
if self.current_assign is None:
|
||||
elem = self.iterable_get(value, index)
|
||||
|
@ -1103,7 +1104,7 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
other_index.add_incoming(next_other_index, body)
|
||||
self.append(ir.Branch(head))
|
||||
|
||||
tail = self.current_block = self.add_block()
|
||||
tail = self.current_block = self.add_block("slice.tail")
|
||||
head.append(ir.BranchIf(within_bounds, body, tail))
|
||||
|
||||
if self.current_assign is None:
|
||||
|
@ -1197,7 +1198,7 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
value_tail = self.current_block
|
||||
|
||||
blocks.append((value, value_head, value_tail))
|
||||
self.current_block = self.add_block()
|
||||
self.current_block = self.add_block("boolop.seq")
|
||||
|
||||
tail = self.current_block
|
||||
phi = self.append(ir.Phi(node.type))
|
||||
|
@ -1366,26 +1367,26 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
|
||||
# If the length is the same, compare element-by-element
|
||||
# and break when the comparison result is false
|
||||
loop_head = self.add_block()
|
||||
loop_head = self.add_block("compare.head")
|
||||
self.current_block = loop_head
|
||||
index_phi = self.append(ir.Phi(self._size_type))
|
||||
index_phi.add_incoming(ir.Constant(0, self._size_type), head)
|
||||
loop_cond = self.append(ir.Compare(ast.Lt(loc=None), index_phi, lhs_length))
|
||||
|
||||
loop_body = self.add_block()
|
||||
loop_body = self.add_block("compare.body")
|
||||
self.current_block = loop_body
|
||||
lhs_elt = self.append(ir.GetElem(lhs, index_phi))
|
||||
rhs_elt = self.append(ir.GetElem(rhs, index_phi))
|
||||
body_result = self.polymorphic_compare_pair(op, lhs_elt, rhs_elt)
|
||||
|
||||
loop_body2 = self.add_block()
|
||||
loop_body2 = self.add_block("compare.body2")
|
||||
self.current_block = loop_body2
|
||||
index_next = self.append(ir.Arith(ast.Add(loc=None), index_phi,
|
||||
ir.Constant(1, self._size_type)))
|
||||
self.append(ir.Branch(loop_head))
|
||||
index_phi.add_incoming(index_next, loop_body2)
|
||||
|
||||
tail = self.add_block()
|
||||
tail = self.add_block("compare.tail")
|
||||
self.current_block = tail
|
||||
phi = self.append(ir.Phi(builtins.TBool()))
|
||||
head.append(ir.BranchIf(eq_length, loop_head, tail))
|
||||
|
@ -1431,14 +1432,14 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
elt = self.iterable_get(haystack, index)
|
||||
cmp_result = self.polymorphic_compare_pair(ast.Eq(loc=None), needle, elt)
|
||||
|
||||
loop_body2 = self.add_block()
|
||||
loop_body2 = self.add_block("compare.body")
|
||||
self.current_block = loop_body2
|
||||
return self.append(ir.Arith(ast.Add(loc=None), index,
|
||||
ir.Constant(1, length.type)))
|
||||
loop_head, loop_body, loop_tail = \
|
||||
self._make_loop(ir.Constant(0, length.type),
|
||||
lambda index: self.append(ir.Compare(ast.Lt(loc=None), index, length)),
|
||||
body_gen)
|
||||
body_gen, name="compare")
|
||||
|
||||
loop_body.append(ir.BranchIf(cmp_result, loop_tail, loop_body2))
|
||||
phi = loop_tail.prepend(ir.Phi(builtins.TBool()))
|
||||
|
@ -1479,7 +1480,7 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
result_tail = self.current_block
|
||||
|
||||
blocks.append((result, result_head, result_tail))
|
||||
self.current_block = self.add_block()
|
||||
self.current_block = self.add_block("compare.seq")
|
||||
lhs = rhs
|
||||
|
||||
tail = self.current_block
|
||||
|
@ -1674,8 +1675,10 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
fn_typ = callee.type
|
||||
offset = 0
|
||||
elif types.is_method(callee.type):
|
||||
func = self.append(ir.GetAttr(callee, "__func__"))
|
||||
self_arg = self.append(ir.GetAttr(callee, "__self__"))
|
||||
func = self.append(ir.GetAttr(callee, "__func__",
|
||||
name="{}.CLS".format(callee.name)))
|
||||
self_arg = self.append(ir.GetAttr(callee, "__self__",
|
||||
name="{}.SLF".format(callee.name)))
|
||||
fn_typ = types.get_method_function(callee.type)
|
||||
offset = 1
|
||||
else:
|
||||
|
@ -1719,7 +1722,7 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
if self.unwind_target is None:
|
||||
insn = self.append(ir.Call(func, args, arg_exprs))
|
||||
else:
|
||||
after_invoke = self.add_block()
|
||||
after_invoke = self.add_block("invoke")
|
||||
insn = self.append(ir.Invoke(func, args, arg_exprs,
|
||||
after_invoke, self.unwind_target))
|
||||
self.current_block = after_invoke
|
||||
|
@ -1734,7 +1737,7 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
|
||||
if node.iodelay is not None and not iodelay.is_const(node.iodelay, 0):
|
||||
before_delay = self.current_block
|
||||
during_delay = self.add_block()
|
||||
during_delay = self.add_block("delay.head")
|
||||
before_delay.append(ir.Branch(during_delay))
|
||||
self.current_block = during_delay
|
||||
|
||||
|
@ -1748,7 +1751,7 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
self.method_map[(attr_node.value.type.find(), attr_node.attr)].append(insn)
|
||||
|
||||
if node.iodelay is not None and not iodelay.is_const(node.iodelay, 0):
|
||||
after_delay = self.add_block()
|
||||
after_delay = self.add_block("delay.tail")
|
||||
self.append(ir.Delay(node.iodelay, insn, after_delay))
|
||||
self.current_block = after_delay
|
||||
|
||||
|
@ -1783,7 +1786,7 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
assert_subexprs = self.current_assert_subexprs = []
|
||||
init = self.current_block
|
||||
|
||||
prehead = self.current_block = self.add_block()
|
||||
prehead = self.current_block = self.add_block("assert.prehead")
|
||||
cond = self.visit(node.test)
|
||||
head = self.current_block
|
||||
finally:
|
||||
|
@ -1795,7 +1798,7 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
init.append(ir.SetLocal(assert_env, subexpr_name, empty))
|
||||
init.append(ir.Branch(prehead))
|
||||
|
||||
if_failed = self.current_block = self.add_block()
|
||||
if_failed = self.current_block = self.add_block("assert.fail")
|
||||
|
||||
if node.msg:
|
||||
explanation = node.msg.s
|
||||
|
@ -1813,7 +1816,7 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
subexpr_cond = self.append(ir.Builtin("is_some", [subexpr_value_opt],
|
||||
builtins.TBool()))
|
||||
|
||||
subexpr_body = self.current_block = self.add_block()
|
||||
subexpr_body = self.current_block = self.add_block("assert.subexpr.body")
|
||||
self.append(ir.Builtin("printf", [
|
||||
ir.Constant(" (%s) = ", builtins.TStr()),
|
||||
ir.Constant(subexpr_node.loc.source(), builtins.TStr())
|
||||
|
@ -1823,14 +1826,14 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
self.polymorphic_print([subexpr_value], separator="", suffix="\n")
|
||||
subexpr_postbody = self.current_block
|
||||
|
||||
subexpr_tail = self.current_block = self.add_block()
|
||||
subexpr_tail = self.current_block = self.add_block("assert.subexpr.tail")
|
||||
self.append(ir.Branch(subexpr_tail), block=subexpr_postbody)
|
||||
self.append(ir.BranchIf(subexpr_cond, subexpr_body, subexpr_tail), block=subexpr_head)
|
||||
|
||||
self.append(ir.Builtin("abort", [], builtins.TNone()))
|
||||
self.append(ir.Unreachable())
|
||||
|
||||
tail = self.current_block = self.add_block()
|
||||
tail = self.current_block = self.add_block("assert.tail")
|
||||
self.append(ir.BranchIf(cond, tail, if_failed), block=head)
|
||||
|
||||
def polymorphic_print(self, values, separator, suffix="", as_repr=False, as_rtio=False):
|
||||
|
@ -1904,10 +1907,10 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||
is_last = self.append(ir.Compare(ast.Lt(loc=None), index, last))
|
||||
head = self.current_block
|
||||
|
||||
if_last = self.current_block = self.add_block()
|
||||
if_last = self.current_block = self.add_block("print.comma")
|
||||
printf(", ")
|
||||
|
||||
tail = self.current_block = self.add_block()
|
||||
tail = self.current_block = self.add_block("print.tail")
|
||||
if_last.append(ir.Branch(tail))
|
||||
head.append(ir.BranchIf(is_last, if_last, tail))
|
||||
|
||||
|
|
|
@ -269,11 +269,11 @@ class LLVMIRGenerator:
|
|||
return llty.as_pointer()
|
||||
else: # Catch-all for exceptions and custom classes
|
||||
if builtins.is_exception(typ):
|
||||
name = "class.Exception" # they all share layout
|
||||
name = "C.Exception" # they all share layout
|
||||
elif types.is_constructor(typ):
|
||||
name = "class.{}".format(typ.name)
|
||||
name = "C.{}".format(typ.name)
|
||||
else:
|
||||
name = "instance.{}".format(typ.name)
|
||||
name = "I.{}".format(typ.name)
|
||||
|
||||
llty = self.llcontext.get_identified_type(name)
|
||||
if llty.elements is None:
|
||||
|
@ -297,7 +297,7 @@ class LLVMIRGenerator:
|
|||
|
||||
if name is None:
|
||||
sanitized_str = re.sub(rb"[^a-zA-Z0-9_.]", b"", as_bytes[:20]).decode('ascii')
|
||||
name = self.llmodule.get_unique_name("str.{}".format(sanitized_str))
|
||||
name = self.llmodule.get_unique_name("S.{}".format(sanitized_str))
|
||||
|
||||
llstr = self.llmodule.get_global(name)
|
||||
if llstr is None:
|
||||
|
@ -439,16 +439,16 @@ class LLVMIRGenerator:
|
|||
else:
|
||||
typ, _ = self.type_map[type(obj_ref)]
|
||||
|
||||
llobject = self.llmodule.get_global("object.{}".format(obj_id))
|
||||
llobject = self.llmodule.get_global("O.{}".format(obj_id))
|
||||
if llobject is not None:
|
||||
llobjects[typ].append(llobject.bitcast(llptr))
|
||||
|
||||
lldatalayout = llvm.create_target_data(self.llmodule.data_layout)
|
||||
|
||||
llrpcattrty = self.llcontext.get_identified_type("attr_desc")
|
||||
llrpcattrty = self.llcontext.get_identified_type("A")
|
||||
llrpcattrty.elements = [lli32, lli32, llptr, llptr]
|
||||
|
||||
lldescty = self.llcontext.get_identified_type("type_desc")
|
||||
lldescty = self.llcontext.get_identified_type("D")
|
||||
lldescty.elements = [llrpcattrty.as_pointer().as_pointer(), llptr.as_pointer()]
|
||||
|
||||
lldescs = []
|
||||
|
@ -457,9 +457,9 @@ class LLVMIRGenerator:
|
|||
continue
|
||||
|
||||
if types.is_constructor(typ):
|
||||
type_name = "class.{}".format(typ.name)
|
||||
type_name = "C.{}".format(typ.name)
|
||||
else:
|
||||
type_name = "instance.{}".format(typ.name)
|
||||
type_name = "I.{}".format(typ.name)
|
||||
|
||||
def llrpcattr_of_attr(name, typ):
|
||||
size = self.llty_of_type(typ). \
|
||||
|
@ -478,14 +478,19 @@ class LLVMIRGenerator:
|
|||
else:
|
||||
llrpctag = ll.Constant(llptr, None)
|
||||
|
||||
llrpcattr = ll.GlobalVariable(self.llmodule, llrpcattrty,
|
||||
name="attr.{}.{}".format(type_name, name))
|
||||
llrpcattr.initializer = ll.Constant(llrpcattrty, [
|
||||
llrpcattrinit = ll.Constant(llrpcattrty, [
|
||||
ll.Constant(lli32, size),
|
||||
ll.Constant(lli32, alignment),
|
||||
llrpctag,
|
||||
self.llstr_of_str(name)
|
||||
])
|
||||
|
||||
if name == "__objectid__":
|
||||
return self.get_or_define_global(name, llrpcattrty, llrpcattrinit)
|
||||
|
||||
llrpcattr = ll.GlobalVariable(self.llmodule, llrpcattrty,
|
||||
name="A.{}.{}".format(type_name, name))
|
||||
llrpcattr.initializer = llrpcattrinit
|
||||
llrpcattr.global_constant = True
|
||||
llrpcattr.unnamed_addr = True
|
||||
llrpcattr.linkage = 'private'
|
||||
|
@ -497,7 +502,7 @@ class LLVMIRGenerator:
|
|||
|
||||
llrpcattraryty = ll.ArrayType(llrpcattrty.as_pointer(), len(llrpcattrs) + 1)
|
||||
llrpcattrary = ll.GlobalVariable(self.llmodule, llrpcattraryty,
|
||||
name="attrs.{}".format(type_name))
|
||||
name="Ax.{}".format(type_name))
|
||||
llrpcattrary.initializer = ll.Constant(llrpcattraryty,
|
||||
llrpcattrs + [ll.Constant(llrpcattrty.as_pointer(), None)])
|
||||
llrpcattrary.global_constant = True
|
||||
|
@ -506,13 +511,13 @@ class LLVMIRGenerator:
|
|||
|
||||
llobjectaryty = ll.ArrayType(llptr, len(llobjects[typ]) + 1)
|
||||
llobjectary = ll.GlobalVariable(self.llmodule, llobjectaryty,
|
||||
name="objects.{}".format(type_name))
|
||||
name="Ox.{}".format(type_name))
|
||||
llobjectary.initializer = ll.Constant(llobjectaryty,
|
||||
llobjects[typ] + [ll.Constant(llptr, None)])
|
||||
llobjectary.linkage = 'private'
|
||||
|
||||
lldesc = ll.GlobalVariable(self.llmodule, lldescty,
|
||||
name="desc.{}".format(type_name))
|
||||
name="D.{}".format(type_name))
|
||||
lldesc.initializer = ll.Constant(lldescty, [
|
||||
llrpcattrary.bitcast(llrpcattrty.as_pointer().as_pointer()),
|
||||
llobjectary.bitcast(llptr.as_pointer())
|
||||
|
@ -548,6 +553,7 @@ class LLVMIRGenerator:
|
|||
llactualargs = self.llfunction.args
|
||||
|
||||
for arg, llarg in zip(func.arguments, llactualargs):
|
||||
llarg.name = arg.name
|
||||
self.llmap[arg] = llarg
|
||||
|
||||
# Second, create all basic blocks.
|
||||
|
@ -649,7 +655,8 @@ class LLVMIRGenerator:
|
|||
def process_GetLocal(self, insn):
|
||||
env = insn.environment()
|
||||
llptr = self.llptr_to_var(self.map(env), env.type, insn.var_name)
|
||||
return self.llbuilder.load(llptr)
|
||||
llptr.name = "ptr.{}.{}".format(env.name, insn.var_name)
|
||||
return self.llbuilder.load(llptr, name="val.{}.{}".format(env.name, insn.var_name))
|
||||
|
||||
def process_SetLocal(self, insn):
|
||||
env = insn.environment()
|
||||
|
@ -658,6 +665,7 @@ class LLVMIRGenerator:
|
|||
# We store NoneType as {} but return it as void. So, bail out here.
|
||||
return ll.Constant(ll.LiteralStructType([]), [])
|
||||
llptr = self.llptr_to_var(self.map(env), env.type, insn.var_name)
|
||||
llptr.name = "ptr.{}.{}".format(env.name, insn.var_name)
|
||||
if isinstance(llvalue, ll.Block):
|
||||
llvalue = ll.BlockAddress(self.llfunction, llvalue)
|
||||
if llptr.type.pointee != llvalue.type:
|
||||
|
@ -687,13 +695,13 @@ class LLVMIRGenerator:
|
|||
def get_class(self, typ):
|
||||
assert types.is_constructor(typ)
|
||||
llty = self.llty_of_type(typ).pointee
|
||||
return self.get_or_define_global("class.{}".format(typ.name), llty)
|
||||
return self.get_or_define_global("C.{}".format(typ.name), llty)
|
||||
|
||||
def get_method(self, typ, attr):
|
||||
assert types.is_constructor(typ)
|
||||
assert types.is_function(typ.attributes[attr])
|
||||
llty = self.llty_of_type(typ.attributes[attr])
|
||||
return self.get_or_define_global("method.{}.{}".format(typ.name, attr), llty)
|
||||
return self.get_or_define_global("M.{}.{}".format(typ.name, attr), llty)
|
||||
|
||||
def process_GetAttr(self, insn):
|
||||
typ, attr = insn.object().type, insn.attr
|
||||
|
@ -715,7 +723,9 @@ class LLVMIRGenerator:
|
|||
assert False
|
||||
|
||||
if types.is_method(insn.type) and attr not in typ.attributes:
|
||||
llfun = self.llbuilder.load(self.get_method(typ.constructor, attr))
|
||||
llmethodptr = self.get_method(typ.constructor, attr)
|
||||
llfun = self.llbuilder.load(llmethodptr)
|
||||
llfun.name = "met.{}.{}".format(typ.constructor.name, attr)
|
||||
llself = self.map(insn.object())
|
||||
|
||||
llmethodty = self.llty_of_type(insn.type)
|
||||
|
@ -727,11 +737,12 @@ class LLVMIRGenerator:
|
|||
return llmethod
|
||||
elif types.is_function(insn.type) and attr in typ.attributes and \
|
||||
types.is_constructor(typ):
|
||||
return self.llbuilder.load(self.get_method(typ, attr))
|
||||
llmethodptr = self.get_method(typ, attr)
|
||||
return self.llbuilder.load(llmethodptr, name="cls.{}".format(llmethodptr.name))
|
||||
else:
|
||||
llptr = self.llbuilder.gep(obj, [self.llindex(0), self.llindex(index)],
|
||||
inbounds=True, name=insn.name)
|
||||
return self.llbuilder.load(llptr)
|
||||
inbounds=True, name="ptr.{}".format(insn.name))
|
||||
return self.llbuilder.load(llptr, name="val.{}".format(insn.name))
|
||||
|
||||
def process_SetAttr(self, insn):
|
||||
typ, attr = insn.object().type, insn.attr
|
||||
|
@ -979,8 +990,8 @@ class LLVMIRGenerator:
|
|||
elif insn.op == "delay_mu":
|
||||
interval, = insn.operands
|
||||
llnowptr = self.llbuiltin("now")
|
||||
llnow = self.llbuilder.load(llnowptr)
|
||||
lladjusted = self.llbuilder.add(llnow, self.map(interval))
|
||||
llnow = self.llbuilder.load(llnowptr, name="now.old")
|
||||
lladjusted = self.llbuilder.add(llnow, self.map(interval), name="now.new")
|
||||
return self.llbuilder.store(lladjusted, llnowptr)
|
||||
elif insn.op == "watchdog_set":
|
||||
interval, = insn.operands
|
||||
|
@ -992,11 +1003,12 @@ class LLVMIRGenerator:
|
|||
assert False
|
||||
|
||||
def process_Closure(self, insn):
|
||||
llenv = self.llbuilder.bitcast(self.map(insn.environment()), llptr)
|
||||
llenv = self.map(insn.environment())
|
||||
llenv = self.llbuilder.bitcast(llenv, llptr, name="ptr.{}".format(llenv.name))
|
||||
if insn.target_function.name in self.function_map.values():
|
||||
# If this closure belongs to a quoted function, we assume this is the only
|
||||
# time that the closure is created, and record the environment globally
|
||||
llenvptr = self.get_or_define_global("env.{}".format(insn.target_function.name),
|
||||
llenvptr = self.get_or_define_global("E.{}".format(insn.target_function.name),
|
||||
llptr)
|
||||
self.llbuilder.store(llenv, llenvptr)
|
||||
|
||||
|
@ -1009,9 +1021,10 @@ class LLVMIRGenerator:
|
|||
def _prepare_closure_call(self, insn):
|
||||
llargs = [self.map(arg) for arg in insn.arguments()]
|
||||
llclosure = self.map(insn.target_function())
|
||||
llenv = self.llbuilder.extract_value(llclosure, 0)
|
||||
llenv = self.llbuilder.extract_value(llclosure, 0, name="env.call")
|
||||
if insn.static_target_function is None:
|
||||
llfun = self.llbuilder.extract_value(llclosure, 1)
|
||||
llfun = self.llbuilder.extract_value(llclosure, 1,
|
||||
name="fun.{}".format(llclosure.name))
|
||||
else:
|
||||
llfun = self.map(insn.static_target_function)
|
||||
return llfun, [llenv] + list(llargs)
|
||||
|
@ -1119,15 +1132,18 @@ class LLVMIRGenerator:
|
|||
|
||||
lltag = self.llstr_of_str(tag)
|
||||
|
||||
llstackptr = self.llbuilder.call(self.llbuiltin("llvm.stacksave"), [])
|
||||
llstackptr = self.llbuilder.call(self.llbuiltin("llvm.stacksave"), [],
|
||||
name="rpc.stack")
|
||||
|
||||
llargs = []
|
||||
for arg in args:
|
||||
for index, arg in enumerate(args):
|
||||
if builtins.is_none(arg.type):
|
||||
llargslot = self.llbuilder.alloca(ll.LiteralStructType([]))
|
||||
llargslot = self.llbuilder.alloca(ll.LiteralStructType([]),
|
||||
name="rpc.arg{}".format(index))
|
||||
else:
|
||||
llarg = self.map(arg)
|
||||
llargslot = self.llbuilder.alloca(llarg.type)
|
||||
llargslot = self.llbuilder.alloca(llarg.type,
|
||||
name="rpc.arg{}".format(index))
|
||||
self.llbuilder.store(llarg, llargslot)
|
||||
llargs.append(llargslot)
|
||||
|
||||
|
@ -1144,36 +1160,39 @@ class LLVMIRGenerator:
|
|||
# else *(T*)ptr
|
||||
# }
|
||||
llprehead = self.llbuilder.basic_block
|
||||
llhead = self.llbuilder.append_basic_block(name=llprehead.name + ".rpc.head")
|
||||
llhead = self.llbuilder.append_basic_block(name="rpc.head")
|
||||
if llunwindblock:
|
||||
llheadu = self.llbuilder.append_basic_block(name=llprehead.name + ".rpc.head.unwind")
|
||||
llalloc = self.llbuilder.append_basic_block(name=llprehead.name + ".rpc.alloc")
|
||||
lltail = self.llbuilder.append_basic_block(name=llprehead.name + ".rpc.tail")
|
||||
llheadu = self.llbuilder.append_basic_block(name="rpc.head.unwind")
|
||||
llalloc = self.llbuilder.append_basic_block(name="rpc.continue")
|
||||
lltail = self.llbuilder.append_basic_block(name="rpc.tail")
|
||||
|
||||
llretty = self.llty_of_type(fun_type.ret)
|
||||
llslot = self.llbuilder.alloca(llretty)
|
||||
llslotgen = self.llbuilder.bitcast(llslot, llptr)
|
||||
llslot = self.llbuilder.alloca(llretty, name="rpc.ret.alloc")
|
||||
llslotgen = self.llbuilder.bitcast(llslot, llptr, name="rpc.ret.ptr")
|
||||
self.llbuilder.branch(llhead)
|
||||
|
||||
self.llbuilder.position_at_end(llhead)
|
||||
llphi = self.llbuilder.phi(llslotgen.type)
|
||||
llphi = self.llbuilder.phi(llslotgen.type, name="rpc.size")
|
||||
llphi.add_incoming(llslotgen, llprehead)
|
||||
if llunwindblock:
|
||||
llsize = self.llbuilder.invoke(self.llbuiltin("recv_rpc"), [llphi],
|
||||
llheadu, llunwindblock)
|
||||
llheadu, llunwindblock,
|
||||
name="rpc.size.next")
|
||||
self.llbuilder.position_at_end(llheadu)
|
||||
else:
|
||||
llsize = self.llbuilder.call(self.llbuiltin("recv_rpc"), [llphi])
|
||||
lldone = self.llbuilder.icmp_unsigned('==', llsize, ll.Constant(llsize.type, 0))
|
||||
llsize = self.llbuilder.call(self.llbuiltin("recv_rpc"), [llphi],
|
||||
name="rpc.size.next")
|
||||
lldone = self.llbuilder.icmp_unsigned('==', llsize, ll.Constant(llsize.type, 0),
|
||||
name="rpc.done")
|
||||
self.llbuilder.cbranch(lldone, lltail, llalloc)
|
||||
|
||||
self.llbuilder.position_at_end(llalloc)
|
||||
llalloca = self.llbuilder.alloca(lli8, llsize)
|
||||
llalloca = self.llbuilder.alloca(lli8, llsize, name="rpc.alloc")
|
||||
llphi.add_incoming(llalloca, llalloc)
|
||||
self.llbuilder.branch(llhead)
|
||||
|
||||
self.llbuilder.position_at_end(lltail)
|
||||
llret = self.llbuilder.load(llslot)
|
||||
llret = self.llbuilder.load(llslot, name="rpc.ret")
|
||||
if not builtins.is_allocated(fun_type.ret):
|
||||
# We didn't allocate anything except the slot for the value itself.
|
||||
# Don't waste stack space.
|
||||
|
@ -1243,7 +1262,7 @@ class LLVMIRGenerator:
|
|||
llglobal = self.get_class(typ)
|
||||
else:
|
||||
llglobal = ll.GlobalVariable(self.llmodule, llty.pointee,
|
||||
name="object.{}".format(objectid))
|
||||
name="O.{}".format(objectid))
|
||||
|
||||
self.llobject_map[value_id] = llglobal
|
||||
else:
|
||||
|
@ -1297,7 +1316,7 @@ class LLVMIRGenerator:
|
|||
def process_Quote(self, insn):
|
||||
if insn.value in self.function_map:
|
||||
func_name = self.function_map[insn.value]
|
||||
llenvptr = self.get_or_define_global("env.{}".format(func_name), llptr)
|
||||
llenvptr = self.get_or_define_global("E.{}".format(func_name), llptr)
|
||||
llenv = self.llbuilder.load(llenvptr)
|
||||
llfun = self.get_function(insn.type.find(), func_name)
|
||||
|
||||
|
|
Loading…
Reference in New Issue