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