To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.7% of users enabled 2FA.

Commit afb70ddc authored by Zixian Cai's avatar Zixian Cai
Browse files

Merge branch 'mu-rewrite' into cfg_interp_prototype

parents 6e79d6df 7920dd72
......@@ -200,3 +200,16 @@ index cafc9b1..380db0d 100644
self._execute_c_compiler(cc, args, exe_name,
cwd=str(exe_name.dirpath()))
return exe_name
diff --git a/rpython/rtyper/lltypesystem/lltype.py b/rpython/rtyper/lltypesystem/lltype.py
index e6239b4324..64a3490e32 100644
--- a/rpython/rtyper/lltypesystem/lltype.py
+++ b/rpython/rtyper/lltypesystem/lltype.py
@@ -1623,7 +1623,7 @@ class _interior_ptr(_abstract_ptr):
if ob is None:
raise RuntimeError
return InteriorPtr(typeOf(ob), self._T, self._offsets)
-## _TYPE = property(_get_TYPE)
+ _TYPE = property(_get_TYPE)
def _expose(self, offset, val):
"""XXX A nice docstring here"""
......@@ -61,6 +61,7 @@ class SizeDescr(AbstractDescr):
tid = llop.combine_ushort(lltype.Signed, 0, 0)
vtable = lltype.nullptr(rclass.OBJECT_VTABLE)
immutable_flag = False
mu_typedescr_str = "typedescr_str"
def __init__(self, size, gc_fielddescrs=None, all_fielddescrs=None,
vtable=lltype.nullptr(rclass.OBJECT_VTABLE),
......
......@@ -651,6 +651,18 @@ class GcLLDescr_framework(GcLLDescription):
def clear_gcref_tracer(self, tracer):
tracer.array_length = 0
class GcLLDescr_mu(GcLLDescr_framework):
def __init__(self, gcdescr, translator, rtyper, llop1=llop,
really_not_translated=False):
from rpython.translator.mu.ll2mu import LL2MuMapper
GcLLDescr_framework.__init__(self, gcdescr, translator, rtyper, llop1, really_not_translated)
self.ll2mu = LL2MuMapper(rtyper)
def init_size_descr(self, S, descr):
MuT = self.ll2mu.map_type(S)
self.ll2mu.resolve_ptr_types()
descr.mu_typedescr_str = self.ll2mu.get_typedescr_str(MuT)
# ____________________________________________________________
def get_ll_description(gcdescr, translator=None, rtyper=None):
......
......@@ -28,6 +28,8 @@ class GC_minimark(GcDescription):
class GC_incminimark(GcDescription):
malloc_zero_filled = False
class GC_mu(GcDescription):
malloc_zero_filled = True
def get_description(config):
name = config.translation.gc
......
......@@ -260,6 +260,10 @@ class MuCommInst:
META_ENABLE_WATCHPOINT = rffi.cast(MuFlag, 0x25e)
META_DISABLE_WATCHPOINT = rffi.cast(MuFlag, 0x25f)
META_SET_TRAP_HANDLER = rffi.cast(MuFlag, 0x260)
META_CONSTANT_BY_ID = rffi.cast(MuFlag, 0x268)
META_GLOBAL_BY_ID = rffi.cast(MuFlag, 0x269)
META_FUNC_BY_ID = rffi.cast(MuFlag, 0x26a)
META_EXPFUNC_BY_ID = rffi.cast(MuFlag, 0x26b)
IRBUILDER_NEW_IR_BUILDER = rffi.cast(MuFlag, 0x270)
IRBUILDER_LOAD = rffi.cast(MuFlag, 0x300)
IRBUILDER_ABORT = rffi.cast(MuFlag, 0x301)
......
......@@ -491,6 +491,10 @@ class MuCommInst:
META_ENABLE_WATCHPOINT = "MU_CI_UVM_META_ENABLE_WATCHPOINT"
META_DISABLE_WATCHPOINT = "MU_CI_UVM_META_DISABLE_WATCHPOINT"
META_SET_TRAP_HANDLER = "MU_CI_UVM_META_SET_TRAP_HANDLER"
META_CONSTANT_BY_ID = "MU_CI_UVM_META_CONSTANT_BY_ID"
META_GLOBAL_BY_ID = "MU_CI_UVM_META_GLOBAL_BY_ID"
META_FUNC_BY_ID = "MU_CI_UVM_META_FUNC_BY_ID"
META_EXPFUNC_BY_ID = "MU_CI_UVM_META_EXPFUNC_BY_ID"
IRBUILDER_NEW_IR_BUILDER = "MU_CI_UVM_IRBUILDER_NEW_IR_BUILDER"
IRBUILDER_LOAD = "MU_CI_UVM_IRBUILDER_LOAD"
IRBUILDER_ABORT = "MU_CI_UVM_IRBUILDER_ABORT"
......
This diff is collapsed.
from rpython.rlib.rmu import holstein_meta as rmu
from rpython.translator.interactive import Translation
from rpython.translator.mu.tool.textgraph import print_graph
from rpython.translator.mu.test.test_mutyper import graph_of
from rpython.translator.mu import mutype, ll2mu
from rpython.rtyper.lltypesystem import lltype, rffi
def test_str2metacstr():
t = Translation(rmu.str2metacstr, [str], backend='mu')
t.backendopt(mallocs=True, inline=True)
g = graph_of(rmu.str2metacstr, t)
print_graph(g)
t.mutype()
print_graph(g)
blk = g.startblock.exits[1].target
assert [op.opname for op in blk.operations[-3:-1]] == ['mu_getiref', 'mu_getvarpartiref']
assert isinstance(blk.operations[-3].result.concretetype, mutype.MuIRef)
def test_str2metabytes():
t = Translation(rmu.str2metabytes, [str], backend='mu')
t.backendopt(mallocs=True, inline=True)
g = graph_of(rmu.str2metabytes, t)
print_graph(g)
t.mutype()
print_graph(g)
assert g.returnblock.inputargs[0].concretetype == mutype.META_BYTES_REF
def test_lst2metaarr():
def f(lst):
return rmu.lst2metacarr(rmu.MuID, lst)
t = Translation(f, [[rmu.MuID]], backend='mu')
t.annotate()
g = graph_of(f, t)
t.backendopt(mallocs=True, inline=True)
t.mutype()
print_graph(g)
assert [op.opname for op in g.startblock.operations[:-1]] == \
['mu_getiref',
'mu_getfieldiref',
'mu_load',
'mu_getiref',
'mu_getvarpartiref',
'mu_shiftiref']
def test_type_translation():
def main(argv):
bldr = rmu.MuIRBuilder()
i8 = bldr.gen_sym("@i8")
bldr.new_type_int(i8, 8)
stt = bldr.gen_sym("@stt")
bldr.new_type_struct(stt, [i8])
bldr.load()
return 0
t = Translation(main, None, backend='mu')
t.annotate()
# t.view()
t.backendopt(mallocs=True, inline=True)
g = graph_of(main, t)
g.view()
print_graph(g)
t.mutype()
g.view()
print_graph(g)
def test_func_by_id():
FUNCPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed))
def f(id):
return rmu.meta_func_by_id(FUNCPTR, id)
t = Translation(f, [rmu.MuID], backend='mu')
t.rtype()
h = graph_of(rmu.meta_func_by_id, t)
assert h.startblock.operations[0].opname == 'mu_meta_xxx_by_id'
t.mutype()
g = graph_of(f, t)
print_graph(g)
op = g.startblock.operations[0]
meta_info = op.args[-1].value
assert 'types' in meta_info
assert meta_info['types'] == [ll2mu.ll2mu_type(FUNCPTR)]
def test_call_meta_compiled_func():
import py
def build_func(bldr):
"""
Builds the following test bundle.
.const @c_1 <@i64> = 1
.funcsig @sig_i64_i64 = (@i64) -> (i@64)
.func @inc VERSION @inc.v1 <@sig_i64_i64> {
%blk0(<@i64> %a):
%a_suc = ADD <@i64> %a @c_1
RET %a_suc
}
:type bldr: rpython.rlib.rmu.holstein_meta.MuIRBuilder
"""
i64 = rmu.meta_id_of("@i64")
c_1 = bldr.gen_sym("@c_1"); bldr.new_const_int(c_1, i64, 1)
sig_i64_i64 = rmu.meta_id_of("@sig_i64_i64") # assume known signature name
# sig_i64_i64 = bldr.gen_sym("@sig_i64_i64_meta") # alternate approach, redefine a signature with another name
# bldr.new_funcsig(sig_i64_i64, [i64], [i64])
stt = bldr.gen_sym(); bldr.new_type_struct(stt, [i64])
inc = bldr.gen_sym("@inc"); bldr.new_func(inc, sig_i64_i64)
blk0 = bldr.gen_sym("@inc.blk0")
a = bldr.gen_sym("@inc.blk0.a")
a_suc = bldr.gen_sym("@inc.blk0.a_suc")
op_add = bldr.gen_sym(); bldr.new_binop(op_add, a_suc, rmu.MuBinOptr.ADD, i64, a, c_1)
op_ret = bldr.gen_sym(); bldr.new_ret(op_ret, [a_suc])
bldr.new_bb(blk0, [a], [i64], rmu.MU_NO_ID, [op_add, op_ret])
bldr.new_func_ver(bldr.gen_sym(), inc, [blk0])
return inc
FUNCPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed))
def main(args):
bldr = rmu.MuIRBuilder()
id_fnc = build_func(bldr)
bldr.load()
a = int(args[1])
inc = rmu.meta_func_by_id(FUNCPTR, id_fnc)
a_inc = inc(a)
print a_inc
return 0
t = Translation(main, None, backend='mu', impl='holstein', codegen='c')
t.driver.standalone = True # force standalone
t.driver.exe_name = '/tmp/test_compile_calls-mu'
t.annotate()
# t.backendopt(mallocs=True)
t.mutype()
t.compile_mu()
img = py.path.local(t.driver.exe_name)
from rpython.rlib.rmu import holstein
from rpython.translator.platform import platform, log as log_platform
runmu = py.path.local(holstein.mu_dir).join('..', 'tools', 'runmu.sh')
flags = ['--vmLog=ERROR', '--losSize=780M', '--sosSize=780M']
args = ['42']
log_platform.execute(' '.join([str(runmu)] + flags + [str(img)] + args))
res = platform.execute(runmu, flags + [str(img)] + args)
assert res.returncode == 0, res.err
assert res.out == '43\n'
......@@ -603,6 +603,9 @@ LL_OPERATIONS = {
# entry point hacks
'mu_thread_exit': LLOp(),
'mu_threadlocalref_init': LLOp(),
# hacks for meta-circular ir building instructions
'mu_meta_barebuf2cstriref': LLOp(),
'mu_meta_lst2carr': LLOp(),
}
# ***** Run test_lloperation after changes. *****
......
......@@ -56,6 +56,7 @@ class MuBundleGen:
lib = find_library(lib)
assert lib
libs.append(lib)
config_items.append('uPtrHack=True') # turn on uptr hack (loading refs from uptr in Mu)
config_items.append('extraLibs=' + ':'.join(libs))
self._holstein_config_extralibs = ':'.join(libs)
if 'vmLog' not in self.mu_config.vmargs:
......@@ -115,6 +116,10 @@ class MuBundleGen:
sys.stderr.write("\033[0F\033[K")
self.log.gen_symbols("generating symbols... (%d/%d %d%%)" % (count, total, count * 100 / total))
# add predefined types in idmap.
for (MuT, (name_str, _id)) in mutype.MU_PREDEF_TYPES.items():
self.idmap[MuT] = _id
def check_reloc_object(self):
"""
Check heap objects that need uptr relocation.
......@@ -245,6 +250,9 @@ class MuBundleGen:
self.bdr.new_type_uptr(_id, self._id_of(T.TO))
elif isinstance(T, mutype.MuWeakRef):
self.bdr.new_type_weakref(_id, self._id_of(T.TO))
elif isinstance(T, mutype.MuOpaqueRef):
if T is mutype.MUTA_IRBUILDER_REF:
self.bdr.new_type_irbuilderref(_id)
def gen_consts(self):
self.log.gen_types("declaring %d constants..." % (len(self.db.consts) + len(self.db.extern_fncs)))
......@@ -475,6 +483,9 @@ class MuBundleGen:
flags, types, sigs,
self._ids_of(op.args[1:-1]))
def _genop_mu_meta_callinternal(self, op, op_id):
pass
def _id_of(self, entity):
# look up id of the entity, if non-existent, call gen_sym
_id = self.idmap[entity]
......
......@@ -123,8 +123,10 @@ class LL2MuMapper:
MuT = self.map_type_arr(LLT)
elif isinstance(LLT, lltype.Ptr):
MuT = self.map_type_ptr(LLT)
elif isinstance(LLT, lltype.OpaqueType):
MuT = self.map_type_opq(LLT)
elif isinstance(LLT, lltype.InteriorPtr):
MuT = self.map_type_iptr(LLT)
# elif isinstance(LLT, lltype.OpaqueType):
# MuT = self.map_type_opq(LLT)
elif LLT is llmemory.WeakRef:
MuT = self.map_wref(LLT)
elif isinstance(LLT, lltype.Typedef):
......@@ -164,6 +166,9 @@ class LL2MuMapper:
raise NotImplementedError("Don't know how to specialise %s using MuTS." % LLT)
def map_type_arrfix(self, LLT):
if LLT.length == 1:
return self.map_type(LLT.OF) # consider length 1 fixed sized array transparent
return mutype.MuArray(self.map_type(LLT.OF), LLT.length)
def map_type_stt(self, LLT):
......@@ -207,6 +212,9 @@ class LL2MuMapper:
return mutype.MuHybrid(name, *flds)
def map_type_arr(self, LLT):
if LLT._hints.get('mu_render_as', None):
return LLT._hints['mu_render_as']
name = "arr" + ("%s" % LLT.OF.__name__ if hasattr(LLT.OF, '__name__') else str(LLT.OF))
if LLT.OF is lltype.Void:
......@@ -215,11 +223,16 @@ class LL2MuMapper:
if LLT._hints.get('render_as_void', False):
return mutype.MU_VOID
flds = [('items', self.map_type(LLT.OF))]
if not LLT._hints.get('nolength', False):
MuT_OF = self.map_type(LLT.OF)
flds = [('items', MuT_OF)]
no_length = LLT._hints.get('nolength', False)
no_hashfield = LLT._hints.get('mu_nohashfield', False)
if not no_length:
flds.insert(0, ('length', mutype.MU_INT64))
if needs_gcheader(LLT):
if not no_hashfield and needs_gcheader(LLT):
flds.insert(0, LL2MuMapper.GC_IDHASH_FIELD)
return mutype.MuHybrid(name, *flds)
......@@ -228,6 +241,9 @@ class LL2MuMapper:
if isinstance(LLT.TO, lltype.FuncType):
return self.map_type_funcptr(LLT)
elif isinstance(LLT.TO, lltype.OpaqueType):
return self.map_type_opqptr(LLT)
if LLT.TO._gckind == 'gc':
cls = mutype.MuRef
else:
......@@ -237,6 +253,11 @@ class LL2MuMapper:
self._pending_ptr_types.append((LLT.TO, MuObjT))
return cls(MuObjT)
def map_type_iptr(self, LLT):
MuObjT = mutype.MuForwardReference()
self._pending_ptr_types.append((LLT.TO, MuObjT))
return mutype.MuIRef(MuObjT)
def resolve_ptr_types(self):
while len(self._pending_ptr_types) > 0:
LLObjT, MuObjT = self._pending_ptr_types.pop()
......@@ -245,12 +266,21 @@ class LL2MuMapper:
def map_type_addr(self, LLT):
return mutype.MuUPtr(mutype.MU_INT8) # NOTE: all Address types are mapped to uptr<int<8>>
def map_type_opq(self, LLT):
if LLT is lltype.RuntimeTypeInfo:
return self.map_type(lltype.Char) # rtti is defined to be a char in C backend.
def map_type_opqptr(self, LLT):
T = LLT.TO
MuT = mutype.MU_INT64 # default to int<64>
return MuT
if T is lltype.RuntimeTypeInfo:
return mutype.MU_VOIDP # rtti is never used;
elif T is llmemory.GCREF.TO:
return mutype.MU_VOIDR # translate GCREF as ref<void>
elif 'mu_render_ptr_as' in T.hints:
return T.hints['mu_render_ptr_as']
if LLT.TO._gckind == 'gc':
cls = mutype.MuRef
else:
cls = mutype.MuUPtr
return cls(mutype.MU_INT64) # default to ref/uptr<int<64>>
def map_type_funcptr(self, LLT):
LLFnc = LLT.TO
......@@ -266,10 +296,36 @@ class LL2MuMapper:
"""
return mutype.MuStruct('WeakRef', ('wref', mutype.MU_WEAKREF_VOID))
def get_typedescr_str(self, MuT): # JIT Mu back-end support
descr_dict = {
mutype.MuRef: 'r',
mutype.MuUPtr: 'p',
mutype.MuFuncRef: 'r', # assuming function ref/uptr has same size as ref/uptr
mutype.MuUFuncPtr: 'p',
mutype.MU_INT8: 'b',
mutype.MU_INT16: 's',
mutype.MU_INT32: 'i',
mutype.MU_INT64: 'l',
mutype.MU_FLOAT: 'f',
mutype.MU_DOUBLE: 'd'
}
if MuT.__class__ in descr_dict:
return descr_dict[MuT.__class__]
if MuT in descr_dict:
return descr_dict[MuT]
if isinstance(MuT, mutype.MuStruct):
return '(%s)' % ''.join(map(self.get_typedescr_str, [getattr(MuT, fld) for fld in MuT._names]))
if isinstance(MuT, mutype.MuHybrid):
fix = ''.join(map(self.get_typedescr_str, [getattr(MuT, fld) for fld in MuT._names[:-1]]))
var = self.get_typedescr_str(MuT._vartype.OF)
return '{%(fix)s|%(var)s}' % locals()
if isinstance(MuT, mutype.MuArray):
return '[%d|%s]' % (MuT.length, self.get_typedescr_str(MuT.OF))
# -----------------------------------------------------------------------------
def map_value(self, llv, **kwargs):
cache, v = (self._ptr_cache, llv._obj) \
if isinstance(llv, lltype._ptr) \
if isinstance(llv, lltype._abstract_ptr) \
else (self._val_cache, llv)
LLT = lltype.typeOf(llv)
key = (LLT, v)
......@@ -291,6 +347,9 @@ class LL2MuMapper:
elif isinstance(llv, lltype._ptr):
muv = self.map_value_ptr(llv)
elif isinstance(llv, lltype._interior_ptr):
muv = self.map_value_iptr(llv)
elif isinstance(llv, lltype._opaque):
muv = self.map_value_opq(llv)
......@@ -379,6 +438,10 @@ class LL2MuMapper:
if LLT._is_varsize():
return self.map_value_varstt(llv)
MuT = self.map_type(LLT)
if MuT is mutype.MU_VOID: # empty struct, struct<>
return None
if topstt not in self._topstt_map:
# build from top
topstt_mu = self.map_value(topstt, building=True)
......@@ -454,16 +517,16 @@ class LL2MuMapper:
if isinstance(LLT.TO, lltype.FuncType):
return self.map_value_funcptr(llv)
if MuT.TO == mutype.MU_VOID:
muv = MuT._null()
# log.warning("Translating LL value '%(llv)r' to '%(muv)r'" % locals())
return muv
ref = MuT._null() # set object later
self._pending_ptr_values.append((llv._obj, ref))
return ref
def map_value_iptr(self, llv):
parent = self.map_value(llv._parent._as_ptr())
MuT = self.map_type(lltype.typeOf(llv))
return mutype._muiref(MuT, parent, llv._offsets)
def resolve_ptr_values(self):
while len(self._pending_ptr_values) > 0:
llv, ref = self._pending_ptr_values.pop()
......@@ -523,8 +586,8 @@ class LL2MuMapper:
def map_value_opq(self, llv):
if llv._TYPE == lltype.RuntimeTypeInfo:
# Since rtti is of char type in C, we use mu_int8 here as well, with an initialised 0 value
return mutype.mu_int8(randint(0, 0xff))
# RuntimeTypeInfo is not used, translate to NULL
return None
if hasattr(llv, 'container'):
container = llv._normalizedcontainer()
......@@ -1511,6 +1574,50 @@ class LL2MuMapper:
def map_op_mu_sizedescr2tid(self, llop):
sd = llop.args[0]
# ----------------
# Meta-circular bundle building API binding support (rmu.*_meta)
def map_op_mu_meta_barebuf2cstriref(self, llop):
# check if arg is ref<hybrid<int<8>>>
Ref = llop.args[0].concretetype
assert isinstance(Ref, mutype.MuRef)
Hyb = Ref.TO
assert isinstance(Hyb, mutype.MuHybrid)
assert len(Hyb._names) == 1 # fixed part empty
assert Hyb._var_field_type() is mutype.MU_INT8
ops = []
iref = varof(mutype.MuIRef(Hyb))
ops.append(self.gen_mu_getiref(llop.args[0], iref))
ops.append(self.gen_mu_getvarpartiref(iref, llop.result))
return ops
def map_op_mu_meta_lst2carr(self, llop):
LIST = llop.args[0].concretetype.TO
if isinstance(LIST, mutype.MuStruct):
REFARR = getattr(LIST, 'items', None)
assert isinstance(REFARR, mutype.MuRef)
assert isinstance(REFARR.TO, mutype.MuHybrid)
refarr = varof(REFARR)
ops = self.map_op(SpaceOperation('getfield', [llop.args[0], Constant('items', mutype.MU_VOID)], refarr))
else:
assert isinstance(LIST, mutype.MuHybrid)
ops = []
refarr = llop.args[0]
iref_itm, _ops = self._getarrayitemiref(refarr, Constant(mutype.mu_int64(0), mutype.MU_INT64))
assert iref_itm.concretetype == llop.result.concretetype
_ops[-1].result = llop.result
ops.extend(_ops)
return ops
def map_op_mu_meta_xxx_by_id(self, llop):
# set 'types' in metainfo, change opname back to mu_comminst
metainfo = llop.args[-1].value
RES_T = llop.result.concretetype
metainfo['types'] = [RES_T]
llop.opname = 'mu_comminst'
return [llop]
# -----------------------------------------------------------------------------
# helper functions for constructing muops
def gen_mu_binop(self, optr, opnd1, opnd2, res=None, status=None, status_results=None, excclause=None):
......@@ -1889,3 +1996,18 @@ _lldebugop_c_externfncs = {
'debug_flush': c_debug_flush,
'have_debug_prints': c_have_debug_prints
}
# conversion functions that can be called without supplying a LL2MuMapper instance
def ll2mu_type(LLT):
ll2mu = LL2MuMapper()
MuT = ll2mu.map_type(LLT)
ll2mu.resolve_ptr_types()
return MuT
def ll2mu_value(llv):
ll2mu = LL2MuMapper()
muv = ll2mu.map_value(llv)
ll2mu.resolve_ptr_values()
return muv
......@@ -1249,6 +1249,24 @@ def castable(REFTYPE, CURTYPE):
raise lltype.InvalidCast(CURTYPE, REFTYPE)
return -u
MU_VOIDR = MuRef(MU_VOID)
MU_VOIDP = MuUPtr(MU_VOID)
META_BYTES = MuHybrid('@uvm.meta.bytes', ('length', MU_INT64), ('bytes', MU_INT8))
META_BYTES_REF = MuRef(META_BYTES)
META_REFS = MuHybrid('@uvm.meta.refs', ('length', MU_INT64), ('refs', MU_VOIDR))
META_REFS_REF = MuRef(META_REFS)
META_MUID = MU_INT32
META_CSTR = MuIRef(MU_INT8)
MUTA_IRBUILDER_REF = MuOpaqueRef('irbuilder')
MU_PREDEF_TYPES = { # predefined types in Mu
META_BYTES: ('@uvm.meta.bytes', mu_int32(0x260)),
META_BYTES_REF: ('@uvm.meta.bytes.r', mu_int32(0x261)),
META_REFS: ('@uvm.meta.refs', mu_int32(0x262)),
META_REFS_REF: ('@uvm.meta.refs.r', mu_int32(0x263)),
}
# ----------------------------------------------------------
_prim_val_type_map = {
......
......@@ -168,7 +168,7 @@ class MuTyper:
assert mutype.mutypeOf(muv) == MuT
if isinstance(muv, mutype._muobject_reference):
if isinstance(muv, mutype._muobject_reference) and not muv._is_null():
GCl_T = mutype.MuGlobalCell(MuT)
if id(muv) in self._objrefid2gcl_dic:
gcl = self._objrefid2gcl_dic[id(muv)]
......@@ -202,6 +202,9 @@ class MuTyper:
'mu_setgcidhash',
'mu_thread_exit',
'mu_threadlocalref_init',
'mu_meta_barebuf2cstriref',
'mu_meta_lst2carr',
'mu_meta_xxx_by_id'
))
llop.args = [self.specialise_arg(arg) for arg in llop.args]
......@@ -324,12 +327,10 @@ def prepare(graphs, entry_graph):
_OPS_KEEP_ALL_ARGS = <