compiler: give environment types in LLVM IR readable names.

This commit is contained in:
whitequark 2015-12-18 23:41:51 +08:00
parent baa986aa32
commit 0395efd479
3 changed files with 20 additions and 10 deletions

View File

@ -500,7 +500,10 @@ class Function:
# Python-specific SSA IR classes # Python-specific SSA IR classes
class TEnvironment(types.TMono): class TEnvironment(types.TMono):
def __init__(self, vars, outer=None): def __init__(self, name, vars, outer=None):
assert isinstance(name, str)
self.env_name = name # for readable type names in LLVM IR
if outer is not None: if outer is not None:
assert isinstance(outer, TEnvironment) assert isinstance(outer, TEnvironment)
env = OrderedDict({"$outer": outer}) env = OrderedDict({"$outer": outer})

View File

@ -181,11 +181,12 @@ class ARTIQIRGenerator(algorithm.Visitor):
entry = self.add_block("entry") entry = self.add_block("entry")
old_block, self.current_block = self.current_block, entry old_block, self.current_block = self.current_block, entry
env = self.append(ir.Alloc([], ir.TEnvironment(node.typing_env), name="env")) env_type = ir.TEnvironment(name=func.name, vars=node.typing_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
priv_env = self.append(ir.Alloc([], ir.TEnvironment({ "$return": typ.ret }), priv_env_type = ir.TEnvironment(name=func.name + ".priv", vars={ "$return": typ.ret })
name="privenv")) priv_env = self.append(ir.Alloc([], priv_env_type, name="privenv"))
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.generic_visit(node) self.generic_visit(node)
@ -264,13 +265,15 @@ class ARTIQIRGenerator(algorithm.Visitor):
{var: node.typing_env[var] {var: node.typing_env[var]
for var in node.typing_env for var in node.typing_env
if var not in node.globals_in_scope} if var not in node.globals_in_scope}
env_type = ir.TEnvironment(env_without_globals, self.current_env.type) 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 old_env, self.current_env = self.current_env, env
if not is_lambda: if not is_lambda:
priv_env = self.append(ir.Alloc([], ir.TEnvironment({ "$return": typ.ret }), priv_env_type = ir.TEnvironment(name=func.name + ".priv",
name="privenv")) vars={ "$return": typ.ret })
priv_env = self.append(ir.Alloc([], priv_env_type, name="privenv"))
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))
@ -1092,7 +1095,9 @@ class ARTIQIRGenerator(algorithm.Visitor):
result = self.append(ir.Alloc([length], node.type)) result = self.append(ir.Alloc([length], node.type))
try: try:
env_type = ir.TEnvironment(node.typing_env, self.current_env.type) gen_suffix = ".gen.{}.{}".format(node.loc.line(), node.loc.column())
env_type = ir.TEnvironment(name=self.current_function.name + gen_suffix,
vars=node.typing_env, outer=self.current_env.type)
env = self.append(ir.Alloc([], env_type, name="env.gen")) env = self.append(ir.Alloc([], env_type, name="env.gen"))
old_env, self.current_env = self.current_env, env old_env, self.current_env = self.current_env, env

View File

@ -256,8 +256,10 @@ class LLVMIRGenerator:
elif ir.is_option(typ): elif ir.is_option(typ):
return ll.LiteralStructType([lli1, 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 = self.llcontext.get_identified_type("env.{}".format(typ.env_name))
for name in typ.params]) if llty.elements is None:
llty.elements = [self.llty_of_type(typ.params[name]) for name in typ.params]
if bare: if bare:
return llty return llty
else: else: