Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/artiq
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 6b28b8e36e1b
Choose a base ref
...
head repository: m-labs/artiq
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: cf418902550d
Choose a head ref
  • 2 commits
  • 2 files changed
  • 1 contributor

Commits on Feb 24, 2016

  1. Copy the full SHA
    4426730 View commit details
  2. Copy the full SHA
    cf41890 View commit details
Showing with 45 additions and 29 deletions.
  1. +41 −29 artiq/compiler/targets.py
  2. +4 −0 artiq/coredevice/exceptions.py
70 changes: 41 additions & 29 deletions artiq/compiler/targets.py
Original file line number Diff line number Diff line change
@@ -43,6 +43,17 @@ def __exit__(self, exc_typ, exc_value, exc_trace):
for f in self.files:
f.close()

def _dump(target, kind, suffix, content):
if target is not None:
print("====== {} DUMP ======".format(kind.upper()), file=sys.stderr)
if target == "":
file = tempfile.NamedTemporaryFile(suffix, delete=False)
else:
file = open(target + suffix, "wb")
file.write(content())
file.close()
print("{} dumped as {}".format(kind, file.name), file=sys.stderr)

class Target:
"""
A description of the target environment where the binaries
@@ -73,25 +84,21 @@ def compile(self, module):
print("====== MODULE_SIGNATURE DUMP ======", file=sys.stderr)
print(module, file=sys.stderr)

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.as_entity(type_printer), file=sys.stderr)
type_printer = types.TypePrinter()
_dump(os.getenv("ARTIQ_DUMP_IR"), "ARTIQ IR", ".txt",
lambda: "\n".join(fn.as_entity(type_printer) for fn in module.artiq_ir))

llmod = module.build_llvm_ir(self)

try:
llparsedmod = llvm.parse_assembly(str(llmod))
llparsedmod.verify()
except RuntimeError:
print("====== LLVM IR DUMP (PARSE FAILED) ======", file=sys.stderr)
print(str(llmod), file=sys.stderr)
_dump("", "LLVM IR (broken)", ".ll", lambda: str(llmod))
raise

if os.getenv("ARTIQ_DUMP_LLVM"):
print("====== LLVM IR DUMP ======", file=sys.stderr)
print(str(llparsedmod), file=sys.stderr)
_dump(os.getenv("ARTIQ_DUMP_UNOPT_LLVM"), "LLVM IR (generated)", "_unopt.ll",
lambda: str(llparsedmod))

llpassmgrbuilder = llvm.create_pass_manager_builder()
llpassmgrbuilder.opt_level = 2 # -O2
@@ -102,18 +109,16 @@ def compile(self, module):
llpassmgrbuilder.populate(llpassmgr)
llpassmgr.run(llparsedmod)

if os.getenv("ARTIQ_DUMP_LLVM"):
print("====== LLVM IR DUMP (OPTIMIZED) ======", file=sys.stderr)
print(str(llparsedmod), file=sys.stderr)
_dump(os.getenv("ARTIQ_DUMP_LLVM"), "LLVM IR (optimized)", ".ll",
lambda: str(llparsedmod))

lltarget = llvm.Target.from_triple(self.triple)
llmachine = lltarget.create_target_machine(
features=",".join(["+{}".format(f) for f in self.features]),
reloc="pic", codemodel="default")

if os.getenv("ARTIQ_DUMP_ASSEMBLY"):
print("====== ASSEMBLY DUMP ======", file=sys.stderr)
print(llmachine.emit_assembly(llparsedmod), file=sys.stderr)
_dump(os.getenv("ARTIQ_DUMP_ASM"), "Assembly", ".s",
lambda: llmachine.emit_assembly(llparsedmod))

return llmachine.emit_object(llparsedmod)

@@ -127,12 +132,8 @@ def link(self, objects, init_fn):
as results:
library = results["output"].read()

if os.getenv("ARTIQ_DUMP_ELF"):
shlib_temp = tempfile.NamedTemporaryFile(suffix=".so", delete=False)
shlib_temp.write(library)
shlib_temp.close()
print("====== SHARED LIBRARY DUMP ======", file=sys.stderr)
print("Shared library dumped as {}".format(shlib_temp.name), file=sys.stderr)
_dump(os.getenv("ARTIQ_DUMP_ELF"), "Shared library", ".so",
lambda: library)

return library

@@ -150,20 +151,31 @@ def symbolize(self, library, addresses):
if addresses == []:
return []

# Addresses point one instruction past the jump; offset them back by 1.
offset_addresses = [hex(addr - 1) for addr in addresses]
with RunTool([self.triple + "-addr2line", "--functions", "--inlines",
offset_addresses = [hex(addr) for addr in addresses]
with RunTool([self.triple + "-addr2line", "--addresses", "--functions", "--inlines",
"--exe={library}"] + offset_addresses,
library=library) \
as results:
lines = results["__stdout__"].rstrip().split("\n")
lines = iter(results["__stdout__"].rstrip().split("\n"))
backtrace = []
for function_name, location, address in zip(lines[::2], lines[1::2], addresses):
while True:
try:
address_or_function = next(lines)
except StopIteration:
break
if address_or_function[:2] == "0x":
address = int(address_or_function[2:], 16)
function = next(lines)
else:
address = backtrace[-1][4] # inlined
function = address_or_function
location = next(lines)

filename, line = location.rsplit(":", 1)
if filename == "??":
if filename == "??" or filename == "<synthesized>":
continue
# can't get column out of addr2line D:
backtrace.append((filename, int(line), -1, function_name, address))
backtrace.append((filename, int(line), -1, function, address))
return backtrace

class NativeTarget(Target):
4 changes: 4 additions & 0 deletions artiq/coredevice/exceptions.py
Original file line number Diff line number Diff line change
@@ -27,15 +27,19 @@ def __init__(self, name, message, params, traceback):
def __str__(self):
lines = []
lines.append("Core Device Traceback (most recent call last):")
last_address = 0
for (filename, line, column, function, address) in self.traceback:
stub_globals = {"__name__": filename, "__loader__": source_loader}
source_line = linecache.getline(filename, line, stub_globals)
indentation = re.search(r"^\s*", source_line).end()

if address is None:
formatted_address = ""
elif address == last_address:
formatted_address = " (inlined)"
else:
formatted_address = " (RA=0x{:x})".format(address)
last_address = address

filename = filename.replace(artiq_dir, "<artiq>")
if column == -1: