Skip to content

Commit

Permalink
compiler: make IR dumps vastly more readable.
Browse files Browse the repository at this point in the history
whitequark committed Nov 16, 2015
1 parent eefa9e2 commit fd46690
Showing 2 changed files with 55 additions and 43 deletions.
94 changes: 52 additions & 42 deletions artiq/compiler/ir.py
Original file line number Diff line number Diff line change
@@ -51,6 +51,9 @@ def replace_all_uses_with(self, value):
for user in set(self.uses):
user.replace_uses_of(self, value)

def __str__(self):
return self.as_entity(type_printer=types.TypePrinter())

class Constant(Value):
"""
A constant value.
@@ -62,11 +65,11 @@ def __init__(self, value, typ):
super().__init__(typ)
self.value = value

def as_operand(self):
return str(self)
def as_operand(self, type_printer):
return self.as_entity(type_printer)

def __str__(self):
return "{} {}".format(types.TypePrinter().name(self.type),
def as_entity(self, type_printer):
return "{} {}".format(type_printer.name(self.type),
repr(self.value))

class NamedValue(Value):
@@ -99,8 +102,8 @@ def _set_function(self, new_function):
def _detach(self):
self.function = None

def as_operand(self):
return "{} %{}".format(types.TypePrinter().name(self.type),
def as_operand(self, type_printer):
return "{} %{}".format(type_printer.name(self.type),
escape_name(self.name))

class User(NamedValue):
@@ -183,18 +186,19 @@ def replace_with(self, value):
else:
self.erase()

def _operands_as_string(self):
return ", ".join([operand.as_operand() for operand in self.operands])
def _operands_as_string(self, type_printer):
return ", ".join([operand.as_operand(type_printer) for operand in self.operands])

def __str__(self):
def as_entity(self, type_printer):
if builtins.is_none(self.type):
prefix = ""
else:
prefix = "%{} = {} ".format(escape_name(self.name),
types.TypePrinter().name(self.type))
type_printer.name(self.type))

if any(self.operands):
return "{}{} {}".format(prefix, self.opcode(), self._operands_as_string())
return "{}{} {}".format(prefix, self.opcode(),
self._operands_as_string(type_printer))
else:
return "{}{}".format(prefix, self.opcode())

@@ -248,15 +252,16 @@ def remove_incoming_block(self, block):
self.operands[index].uses.remove(self)
del self.operands[index - 1:index + 1]

def __str__(self):
def as_entity(self, type_printer):
if builtins.is_none(self.type):
prefix = ""
else:
prefix = "%{} = {} ".format(escape_name(self.name),
types.TypePrinter().name(self.type))
type_printer.name(self.type))

if any(self.operands):
operand_list = ["%{} => {}".format(escape_name(block.name), value.as_operand())
operand_list = ["%{} => {}".format(escape_name(block.name),
value.as_operand(type_printer))
for value, block in self.incoming()]
return "{}{} [{}]".format(prefix, self.opcode(), ", ".join(operand_list))
else:
@@ -346,7 +351,7 @@ def successors(self):
def predecessors(self):
return [use.basic_block for use in self.uses if isinstance(use, Terminator)]

def __str__(self):
def as_entity(self, type_printer):
# Header
lines = ["{}:".format(escape_name(self.name))]
if self.function is not None:
@@ -372,7 +377,7 @@ def __str__(self):
line_desc = "{}:{}".format(loc.source_buffer.name, loc.line())
lines += ["; {} {}".format(line_desc, line.rstrip("\n"))
for line in source_lines]
lines.append(" " + str(insn))
lines.append(" " + insn.as_entity(type_printer))

return "\n".join(lines)

@@ -384,8 +389,8 @@ class Argument(NamedValue):
A function argument.
"""

def __str__(self):
return self.as_operand()
def as_entity(self, type_printer):
return self.as_operand(type_printer)

class Function:
"""
@@ -447,18 +452,20 @@ def instructions(self):
for basic_block in self.basic_blocks:
yield from iter(basic_block.instructions)

def __str__(self):
printer = types.TypePrinter()
def as_entity(self, type_printer):
lines = []
lines.append("{} {}({}) {{ ; type: {}".format(
printer.name(self.type.ret), self.name,
", ".join([arg.as_operand() for arg in self.arguments]),
printer.name(self.type)))
type_printer.name(self.type.ret), self.name,
", ".join([arg.as_operand(type_printer) for arg in self.arguments]),
type_printer.name(self.type)))
for block in self.basic_blocks:
lines.append(str(block))
lines.append(block.as_entity(type_printer))
lines.append("}")
return "\n".join(lines)

def __str__(self):
return self.as_entity(types.TypePrinter())

# Python-specific SSA IR classes

class TEnvironment(types.TMono):
@@ -511,7 +518,7 @@ class EnvironmentArgument(Argument):
A function argument specifying an outer environment.
"""

def as_operand(self):
def as_operand(self, type_printer):
return "environment(...) %{}".format(escape_name(self.name))

class Alloc(Instruction):
@@ -527,12 +534,12 @@ def __init__(self, operands, typ, name=""):
def opcode(self):
return "alloc"

def as_operand(self):
def as_operand(self, type_printer):
if is_environment(self.type):
# Only show full environment in the instruction itself
return "%{}".format(escape_name(self.name))
else:
return super().as_operand()
return super().as_operand(type_printer)

class GetLocal(Instruction):
"""
@@ -875,8 +882,8 @@ def target_function(self):
def arguments(self):
return self.operands[1:]

def __str__(self):
result = super().__str__()
def as_entity(self, type_printer):
result = super().as_entity(type_printer)
if self.static_target_function is not None:
result += " ; calls {}".format(self.static_target_function.name)
return result
@@ -1003,9 +1010,10 @@ def add_destination(self, destination):
destination.uses.add(self)
self.operands.append(destination)

def _operands_as_string(self):
return "{}, [{}]".format(self.operands[0].as_operand(),
", ".join([dest.as_operand() for dest in self.operands[1:]]))
def _operands_as_string(self, type_printer):
return "{}, [{}]".format(self.operands[0].as_operand(type_printer),
", ".join([dest.as_operand(type_printer)
for dest in self.operands[1:]]))

class Return(Terminator):
"""
@@ -1125,14 +1133,14 @@ def normal_target(self):
def exception_target(self):
return self.operands[-1]

def _operands_as_string(self):
result = ", ".join([operand.as_operand() for operand in self.operands[:-2]])
result += " to {} unwind {}".format(self.operands[-2].as_operand(),
self.operands[-1].as_operand())
def _operands_as_string(self, type_printer):
result = ", ".join([operand.as_operand(type_printer) for operand in self.operands[:-2]])
result += " to {} unwind {}".format(self.operands[-2].as_operand(type_printer),
self.operands[-1].as_operand(type_printer))
return result

def __str__(self):
result = super().__str__()
def as_entity(self, type_printer):
result = super().as_entity(type_printer)
if self.static_target_function is not None:
result += " ; calls {}".format(self.static_target_function.name)
return result
@@ -1169,14 +1177,16 @@ def add_clause(self, target, typ):
self.types.append(typ.find() if typ is not None else None)
target.uses.add(self)

def _operands_as_string(self):
def _operands_as_string(self, type_printer):
table = []
for target, typ in self.clauses():
if typ is None:
table.append("... => {}".format(target.as_operand()))
table.append("... => {}".format(target.as_operand(type_printer)))
else:
table.append("{} => {}".format(types.TypePrinter().name(typ), target.as_operand()))
return "cleanup {}, [{}]".format(self.cleanup().as_operand(), ", ".join(table))
table.append("{} => {}".format(type_printer.name(typ),
target.as_operand(type_printer)))
return "cleanup {}, [{}]".format(self.cleanup().as_operand(type_printer),
", ".join(table))

class Parallel(Terminator):
"""
4 changes: 3 additions & 1 deletion artiq/compiler/targets.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os, sys, tempfile, subprocess
from artiq.compiler import types
from llvmlite_artiq import ir as ll, binding as llvm

llvm.initialize()
@@ -75,8 +76,9 @@ def compile(self, module):

if os.getenv("ARTIQ_DUMP_IR"):
print("====== ARTIQ IR DUMP ======", file=sys.stderr)
type_printer = types.TypePrinter()
for function in module.artiq_ir:
print(function, file=sys.stderr)
print(function.as_entity(type_printer), file=sys.stderr)

llmod = module.build_llvm_ir(self)
llparsedmod = llvm.parse_assembly(str(llmod))

0 comments on commit fd46690

Please sign in to comment.