compiler: T{C -> External}Function, clarify docs [nfc]

pull/1508/head
David Nadlinger 2020-08-02 13:42:24 +01:00
parent da255bee1b
commit d37503f21d
6 changed files with 34 additions and 23 deletions

View File

@ -334,6 +334,6 @@ def is_allocated(typ):
return not (is_none(typ) or is_bool(typ) or is_int(typ) or
is_float(typ) or is_range(typ) or
types._is_pointer(typ) or types.is_function(typ) or
types.is_c_function(typ) or types.is_rpc(typ) or
types.is_external_function(typ) or types.is_rpc(typ) or
types.is_method(typ) or types.is_tuple(typ) or
types.is_value(typ))

View File

@ -1001,9 +1001,9 @@ class Stitcher:
self.engine.process(diag)
ret_type = types.TVar()
function_type = types.TCFunction(arg_types, ret_type,
name=function.artiq_embedded.syscall,
flags=function.artiq_embedded.flags)
function_type = types.TExternalFunction(arg_types, ret_type,
name=function.artiq_embedded.syscall,
flags=function.artiq_embedded.flags)
self.functions[function] = function_type
return function_type

View File

@ -2137,7 +2137,7 @@ class ARTIQIRGenerator(algorithm.Visitor):
assert None not in args
if self.unwind_target is None or \
types.is_c_function(callee.type) and "nounwind" in callee.type.flags:
types.is_external_function(callee.type) and "nounwind" in callee.type.flags:
insn = self.append(ir.Call(func, args, arg_exprs))
else:
after_invoke = self.add_block("invoke")

View File

@ -205,7 +205,7 @@ class LLVMIRGenerator:
typ = typ.find()
if types.is_tuple(typ):
return ll.LiteralStructType([self.llty_of_type(eltty) for eltty in typ.elts])
elif types.is_rpc(typ) or types.is_c_function(typ):
elif types.is_rpc(typ) or types.is_external_function(typ):
if for_return:
return llvoid
else:
@ -838,7 +838,7 @@ class LLVMIRGenerator:
closure_type = typ.attributes[attr]
assert types.is_constructor(typ)
assert types.is_function(closure_type) or types.is_rpc(closure_type)
if types.is_c_function(closure_type) or types.is_rpc(closure_type):
if types.is_external_function(closure_type) or types.is_rpc(closure_type):
return None
llty = self.llty_of_type(typ.attributes[attr])
@ -1443,7 +1443,7 @@ class LLVMIRGenerator:
functiontyp,
insn.arguments(),
llnormalblock=None, llunwindblock=None)
elif types.is_c_function(functiontyp):
elif types.is_external_function(functiontyp):
llfun, llargs = self._prepare_ffi_call(insn)
else:
llfun, llargs = self._prepare_closure_call(insn)
@ -1466,7 +1466,7 @@ class LLVMIRGenerator:
# Never add TBAA nowrite metadata to a functon with sret!
# This leads to miscompilations.
if types.is_c_function(functiontyp) and 'nowrite' in functiontyp.flags:
if types.is_external_function(functiontyp) and 'nowrite' in functiontyp.flags:
llcall.set_metadata('tbaa', self.tbaa_nowrite_call)
return llresult
@ -1480,7 +1480,7 @@ class LLVMIRGenerator:
functiontyp,
insn.arguments(),
llnormalblock, llunwindblock)
elif types.is_c_function(functiontyp):
elif types.is_external_function(functiontyp):
llfun, llargs = self._prepare_ffi_call(insn)
else:
llfun, llargs = self._prepare_closure_call(insn)
@ -1530,7 +1530,7 @@ class LLVMIRGenerator:
attrvalue = getattr(value, attr)
is_class_function = (types.is_constructor(typ) and
types.is_function(typ.attributes[attr]) and
not types.is_c_function(typ.attributes[attr]))
not types.is_external_function(typ.attributes[attr]))
if is_class_function:
attrvalue = self.embedding_map.specialize_function(typ.instance, attrvalue)
if not (types.is_instance(typ) and attr in typ.constant_attributes):
@ -1600,7 +1600,7 @@ class LLVMIRGenerator:
llelts = [self._quote(v, t, lambda: path() + [str(i)])
for i, (v, t) in enumerate(zip(value, typ.elts))]
return ll.Constant(llty, llelts)
elif types.is_rpc(typ) or types.is_c_function(typ) or types.is_builtin_function(typ):
elif types.is_rpc(typ) or types.is_external_function(typ) or types.is_builtin_function(typ):
# RPC, C and builtin functions have no runtime representation.
return ll.Constant(llty, ll.Undefined)
elif types.is_function(typ):

View File

@ -283,12 +283,18 @@ class TFunction(Type):
def __hash__(self):
return hash((_freeze(self.args), _freeze(self.optargs), self.ret))
class TCFunction(TFunction):
class TExternalFunction(TFunction):
"""
A function type of a runtime-provided C function.
A type of an externally-provided function.
:ivar name: (str) C function name
:ivar flags: (set of str) C function flags.
This can be any function following the C ABI, such as provided by the
C/Rust runtime, or a compiler backend intrinsic. The mangled name to link
against is encoded as part of the type.
:ivar name: (str) external symbol name.
This will be the symbol linked against (following any extra C name
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
that the ARTIQ Python code can observe.
@ -308,7 +314,7 @@ class TCFunction(TFunction):
def unify(self, other):
if other is self:
return
if isinstance(other, TCFunction) and \
if isinstance(other, TExternalFunction) and \
self.name == other.name:
super().unify(other)
elif isinstance(other, TVar):
@ -404,6 +410,11 @@ class TBuiltin(Type):
class TBuiltinFunction(TBuiltin):
"""
A type of a builtin function.
Builtin functions are treated specially throughout all stages of the
compilation process according to their name (e.g. calls may not actually
lower to a function call). See :class:`TExternalFunction` for externally
defined functions that are otherwise regular.
"""
class TConstructor(TBuiltin):
@ -609,12 +620,12 @@ def is_function(typ):
def is_rpc(typ):
return isinstance(typ.find(), TRPC)
def is_c_function(typ, name=None):
def is_external_function(typ, name=None):
typ = typ.find()
if name is None:
return isinstance(typ, TCFunction)
return isinstance(typ, TExternalFunction)
else:
return isinstance(typ, TCFunction) and \
return isinstance(typ, TExternalFunction) and \
typ.name == name
def is_builtin(typ, name=None):
@ -744,7 +755,7 @@ class TypePrinter(object):
return "(%s,)" % self.name(typ.elts[0], depth + 1)
else:
return "(%s)" % ", ".join([self.name(typ, depth + 1) for typ in typ.elts])
elif isinstance(typ, (TFunction, TCFunction)):
elif isinstance(typ, (TFunction, TExternalFunction)):
args = []
args += [ "%s:%s" % (arg, self.name(typ.args[arg], depth + 1))
for arg in typ.args]
@ -758,7 +769,7 @@ class TypePrinter(object):
elif not (delay.is_fixed() and iodelay.is_zero(delay.duration)):
signature += " " + self.name(delay, depth + 1)
if isinstance(typ, TCFunction):
if isinstance(typ, TExternalFunction):
return "[ffi {}]{}".format(repr(typ.name), signature)
elif isinstance(typ, TFunction):
return signature

View File

@ -99,7 +99,7 @@ class RegionOf(algorithm.Visitor):
visit_BinOpT = visit_sometimes_allocating
def visit_CallT(self, node):
if types.is_c_function(node.func.type, "cache_get"):
if types.is_external_function(node.func.type, "cache_get"):
# The cache is borrow checked dynamically
return Global()
else: