To protect your data, the CISO officer has suggested users to enable GitLab 2FA as soon as possible.

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 =