2
0
mirror of https://github.com/m-labs/artiq.git synced 2024-12-25 03:08:27 +08:00

syscall: lower nowrite to inaccessiblememonly

In the origin implementation, the `nowrite` flag literally means not writing memory at all.
Due to the usage of flags on certain functions, it results in the same issues found in artiq-zynq after optimization passes. (M-Labs/artiq-zynq#119)
A fix wrote by @dnadlinger can resolve this issue. (c1e46cc7c8)
This commit is contained in:
occheung 2021-08-30 10:53:42 +08:00
parent 6db7280b09
commit 5985f7efb5
4 changed files with 7 additions and 18 deletions

View File

@ -84,14 +84,6 @@ class LLVMIRGenerator:
self.llobject_map = {}
self.phis = []
self.empty_metadata = self.llmodule.add_metadata([])
self.tbaa_tree = self.llmodule.add_metadata([
ll.MetaDataString(self.llmodule, "ARTIQ TBAA")
])
self.tbaa_nowrite_call = self.llmodule.add_metadata([
ll.MetaDataString(self.llmodule, "ref-only function call"),
self.tbaa_tree,
ll.Constant(lli64, 1)
])
self.quote_fail_msg = None
def needs_sret(self, lltyp, may_be_large=True):
@ -1207,6 +1199,8 @@ class LLVMIRGenerator:
llfun.args[i].add_attribute('byval')
if 'nounwind' in insn.target_function().type.flags:
llfun.attributes.add('nounwind')
if 'nowrite' in insn.target_function().type.flags:
llfun.attributes.add('inaccessiblememonly')
return llfun, list(llargs)
@ -1364,11 +1358,6 @@ class LLVMIRGenerator:
# {} elsewhere.
llresult = ll.Constant(llunit, [])
# Never add TBAA nowrite metadata to a functon with sret!
# This leads to miscompilations.
if types.is_external_function(functiontyp) and 'nowrite' in functiontyp.flags:
llcall.set_metadata('tbaa', self.tbaa_nowrite_call)
return llresult
def process_Invoke(self, insn):

View File

@ -304,7 +304,7 @@ class TExternalFunction(TFunction):
mangling rules).
:ivar flags: (set of str) function flags.
Flag ``nounwind`` means the function never raises an exception.
Flag ``nowrite`` means the function never writes any memory
Flag ``nowrite`` means the function never accesses any memory
that the ARTIQ Python code can observe.
:ivar broadcast_across_arrays: (bool)
If True, the function is transparently applied element-wise when called

View File

@ -2,11 +2,11 @@ from artiq.language.core import *
from artiq.language.types import *
@syscall(flags={"nounwind", "nowrite"})
@syscall(flags={"nounwind"})
def cache_get(key: TStr) -> TList(TInt32):
raise NotImplementedError("syscall not simulated")
@syscall(flags={"nowrite"})
@syscall
def cache_put(key: TStr, value: TList(TInt32)) -> TNone:
raise NotImplementedError("syscall not simulated")

View File

@ -4,9 +4,9 @@
from artiq.language.core import *
from artiq.language.types import *
# CHECK: call void @foo\(\)(, !dbg !\d+)?, !tbaa !\d+
# CHECK: call void @foo\(\)(, !dbg !\d+)?
# CHECK-L: ; Function Attrs: nounwind
# CHECK-L: ; Function Attrs: inaccessiblememonly nounwind
# CHECK-NEXT-L: declare void @foo()
@syscall(flags={"nounwind", "nowrite"})