From a9489246a459b5aa51887580939dc8b5e227b43d Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 29 Mar 2016 12:54:36 +0000 Subject: [PATCH 1/5] llvm_ir_generator: don't mark non-constant attribute loads as invariant. Oops. --- artiq/compiler/transforms/llvm_ir_generator.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/artiq/compiler/transforms/llvm_ir_generator.py b/artiq/compiler/transforms/llvm_ir_generator.py index 8082595f9..22f60fdde 100644 --- a/artiq/compiler/transforms/llvm_ir_generator.py +++ b/artiq/compiler/transforms/llvm_ir_generator.py @@ -811,7 +811,8 @@ class LLVMIRGenerator: llptr = self.llbuilder.gep(obj, [self.llindex(0), self.llindex(index)], inbounds=True, name="ptr.{}".format(insn.name)) llval = self.llbuilder.load(llptr, name="val.{}".format(insn.name)) - llval.metadata['invariant.load'] = self.empty_metadata + if types.is_instance(typ) and attr not in typ.constant_attributes: + llval.metadata['invariant.load'] = self.empty_metadata return llval def process_SetAttr(self, insn): From f6b391bb4ebc2accb548cbc5f819977047cf9c15 Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 29 Mar 2016 13:02:14 +0000 Subject: [PATCH 2/5] compiler: fix ARTIQ_DUMP_ELF. --- artiq/compiler/targets.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/artiq/compiler/targets.py b/artiq/compiler/targets.py index 34f85d85f..ba79e0121 100644 --- a/artiq/compiler/targets.py +++ b/artiq/compiler/targets.py @@ -46,12 +46,14 @@ class RunTool: def _dump(target, kind, suffix, content): if target is not None: print("====== {} DUMP ======".format(kind.upper()), file=sys.stderr) - content_bytes = bytes(content(), 'utf-8') + content_value = content() + if isinstance(content_value, str): + content_value = bytes(content_value, 'utf-8') if target == "": file = tempfile.NamedTemporaryFile(suffix=suffix, delete=False) else: file = open(target + suffix, "wb") - file.write(content_bytes) + file.write(content_value) file.close() print("{} dumped as {}".format(kind, file.name), file=sys.stderr) From 330b2326728d616a82f290fea37e6818f94cdf61 Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 29 Mar 2016 13:10:38 +0000 Subject: [PATCH 3/5] test: relax lit/embedding/syscall_flags. We currently have broken debug info. In either case, debug info is irrelevant to this test. --- artiq/test/lit/embedding/syscall_flags.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/artiq/test/lit/embedding/syscall_flags.py b/artiq/test/lit/embedding/syscall_flags.py index 15636507f..7d2a10341 100644 --- a/artiq/test/lit/embedding/syscall_flags.py +++ b/artiq/test/lit/embedding/syscall_flags.py @@ -4,7 +4,7 @@ from artiq.language.core import * from artiq.language.types import * -# CHECK: call void @foo\(\), !dbg !\d+, !tbaa !\d+ +# CHECK: call void @foo\(\)(, !dbg !\d+)?, !tbaa !\d+ # CHECK-L: ; Function Attrs: nounwind # CHECK-NEXT-L: declare void @foo() From 586022023b6a213a0fd566876a7ba8197fcfe952 Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 29 Mar 2016 13:03:15 +0000 Subject: [PATCH 4/5] llvm_ir_generator: mark loads as non-null where applicable. --- .../compiler/transforms/llvm_ir_generator.py | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/artiq/compiler/transforms/llvm_ir_generator.py b/artiq/compiler/transforms/llvm_ir_generator.py index 22f60fdde..20aa97c3d 100644 --- a/artiq/compiler/transforms/llvm_ir_generator.py +++ b/artiq/compiler/transforms/llvm_ir_generator.py @@ -685,13 +685,17 @@ class LLVMIRGenerator: inbounds=True) llouterenv = self.llbuilder.load(llptr) llouterenv.metadata['invariant.load'] = self.empty_metadata + llouterenv.metadata['nonnull'] = self.empty_metadata return self.llptr_to_var(llouterenv, env_ty.params["$outer"], var_name) def process_GetLocal(self, insn): env = insn.environment() llptr = self.llptr_to_var(self.map(env), env.type, insn.var_name) llptr.name = "ptr.{}.{}".format(env.name, insn.var_name) - return self.llbuilder.load(llptr, name="val.{}.{}".format(env.name, insn.var_name)) + llvalue = self.llbuilder.load(llptr, name="val.{}.{}".format(env.name, insn.var_name)) + if isinstance(llvalue.type, ll.PointerType): + llvalue.metadata['nonnull'] = self.empty_metadata + return llvalue def process_SetLocal(self, insn): env = insn.environment() @@ -810,10 +814,12 @@ class LLVMIRGenerator: else: llptr = self.llbuilder.gep(obj, [self.llindex(0), self.llindex(index)], inbounds=True, name="ptr.{}".format(insn.name)) - llval = self.llbuilder.load(llptr, name="val.{}".format(insn.name)) - if types.is_instance(typ) and attr not in typ.constant_attributes: - llval.metadata['invariant.load'] = self.empty_metadata - return llval + llvalue = self.llbuilder.load(llptr, name="val.{}".format(insn.name)) + if types.is_instance(typ) and attr in typ.constant_attributes: + llvalue.metadata['invariant.load'] = self.empty_metadata + if isinstance(llvalue.type, ll.PointerType): + llvalue.metadata['nonnull'] = self.empty_metadata + return llvalue def process_SetAttr(self, insn): typ, attr = insn.object().type, insn.attr @@ -841,7 +847,10 @@ class LLVMIRGenerator: llelts = self.llbuilder.extract_value(self.map(insn.list()), 1) llelt = self.llbuilder.gep(llelts, [self.map(insn.index())], inbounds=True) - return self.llbuilder.load(llelt) + llvalue = self.llbuilder.load(llelt) + if isinstance(llvalue.type, ll.PointerType): + llvalue.metadata['nonnull'] = self.empty_metadata + return llvalue def process_SetElem(self, insn): llelts = self.llbuilder.extract_value(self.map(insn.list()), 1) @@ -1052,6 +1061,7 @@ class LLVMIRGenerator: inbounds=True) llouterenv = self.llbuilder.load(llptr) llouterenv.metadata['invariant.load'] = self.empty_metadata + llouterenv.metadata['nonnull'] = self.empty_metadata return self.llptr_to_var(llouterenv, env_ty.params["$outer"], var_name) else: return llenv From 8a908a7656c302abf4057a21e27ad4cf1d6925ca Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 29 Mar 2016 15:19:46 +0000 Subject: [PATCH 5/5] llvm_ir_generator: do not use 'coldcc' calling convention. First, this calling convention doesn't actually exist in OR1K and trying to use it in Asserts build causes an UNREACHABLE. Second, I tried to introduce it and it does not appear to produce any measurable benefit: not only OR1K has a ton of CSRs but also it is quite hard, if not realistically impossible, to produce the kind of register pressure that would be relieved by sparing a few more CSRs for our exception raising function calls, since temporaries don't have to be preserved before a noreturn call and spilling over ten registers across an exceptional edge is not something that the code we care about would do. Third, it produces measurable drawbacks: it inflates code size of check:* functions by adding spills. Of course, this could be alleviated by making __artiq_raise coldcc as well, but what's the point anyway? --- artiq/compiler/transforms/llvm_ir_generator.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/artiq/compiler/transforms/llvm_ir_generator.py b/artiq/compiler/transforms/llvm_ir_generator.py index 20aa97c3d..474dbd883 100644 --- a/artiq/compiler/transforms/llvm_ir_generator.py +++ b/artiq/compiler/transforms/llvm_ir_generator.py @@ -569,7 +569,6 @@ class LLVMIRGenerator: if func.is_internal: self.llfunction.linkage = 'private' if func.is_cold: - self.llfunction.calling_convention = 'coldcc' self.llfunction.attributes.add('cold') self.llfunction.attributes.add('noinline') @@ -1322,9 +1321,6 @@ class LLVMIRGenerator: if types.is_c_function(functiontyp) and 'nowrite' in functiontyp.flags: llcall.metadata['tbaa'] = self.tbaa_nowrite_call - if insn.is_cold: - llcall.cconv = 'coldcc' - return llresult def process_Invoke(self, insn): @@ -1358,9 +1354,6 @@ class LLVMIRGenerator: if types.is_c_function(functiontyp) and 'nowrite' in functiontyp.flags: llcall.metadata['tbaa'] = self.tbaa_nowrite_call - if insn.is_cold: - llcall.cconv = 'coldcc' - return llcall def _quote(self, value, typ, path):