Commit 7b483027 authored by John Zhang's avatar John Zhang

Merge branch 'mu-rewrite' into debug-pypy-interp

parents b76b98b4 bc1ff4e5
......@@ -66,7 +66,7 @@ class LL2MuMapper:
self.mlha.rtyper.annotator.translator.graphs)[0]
fnp = lltype.functionptr(lltype.FuncType(
[a.concretetype for a in g.startblock.inputargs], g.returnblock.inputargs[0].concretetype),
g.name, graph=g)
g.name, graph=g)
str2charp_c = Constant(fnp, lltype.typeOf(fnp))
except IndexError:
str2charp_c = self.mlha.constfunc(rffi.str2charp, [SomeString(), SomeBool()], l2a(rffi.CCHARP))
......@@ -125,8 +125,8 @@ class LL2MuMapper:
MuT = self.map_type_ptr(LLT)
elif isinstance(LLT, lltype.InteriorPtr):
MuT = self.map_type_iptr(LLT)
# elif isinstance(LLT, lltype.OpaqueType):
# MuT = self.map_type_opq(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):
......@@ -138,20 +138,20 @@ class LL2MuMapper:
def map_type_prim(self, LLT):
type_map = {
lltype.Signed: mutype.MU_INT64,
lltype.Unsigned: mutype.MU_INT64,
lltype.SignedLongLong: mutype.MU_INT64,
lltype.UnsignedLongLong: mutype.MU_INT64,
lltype.SignedLongLongLong: mutype.MU_INT128,
lltype.Float: mutype.MU_DOUBLE,
lltype.SingleFloat: mutype.MU_FLOAT,
lltype.LongFloat: mutype.MU_DOUBLE,
lltype.Char: mutype.MU_INT8,
lltype.Bool: mutype.MU_INT8,
lltype.Void: mutype.MU_VOID,
lltype.UniChar: mutype.MU_INT32, # wchar_t is 32-bits on OS X and Linux 64-bit machines
lltype.Signed: mutype.MU_INT64,
lltype.Unsigned: mutype.MU_INT64,
lltype.SignedLongLong: mutype.MU_INT64,
lltype.UnsignedLongLong: mutype.MU_INT64,
lltype.SignedLongLongLong: mutype.MU_INT128,
lltype.Float: mutype.MU_DOUBLE,
lltype.SingleFloat: mutype.MU_FLOAT,
lltype.LongFloat: mutype.MU_DOUBLE,
lltype.Char: mutype.MU_INT8,
lltype.Bool: mutype.MU_INT8,
lltype.Void: mutype.MU_VOID,
lltype.UniChar: mutype.MU_INT32, # wchar_t is 32-bits on OS X and Linux 64-bit machines
}
try:
return type_map[LLT]
......@@ -162,12 +162,12 @@ class LL2MuMapper:
return getattr(mutype, "MU_INT%d" % b)
else:
return mutype.MuIntType("MU_INT%d" % b,
rarithmetic.build_int('r_uint%d' % b, False, b)) # unsigned
rarithmetic.build_int('r_uint%d' % b, False, b)) # unsigned
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 self.map_type(LLT.OF) # consider length 1 fixed sized array transparent
return mutype.MuArray(self.map_type(LLT.OF), LLT.length)
......@@ -280,7 +280,21 @@ class LL2MuMapper:
cls = mutype.MuRef
else:
cls = mutype.MuUPtr
return cls(mutype.MU_INT64) # default to ref/uptr<int<64>>
try:
MuT = self.map_type(T)
except NotImplementedError:
MuT = mutype.MU_INT64 # default to ref/uptr<int<64>>
return cls(MuT)
def map_type_opq(self, LLT):
# sometimes we still need to map opaque types, such as fd_set (_rsocket_rffi.fd_set)
# translate to array with the same size
if 'getsize' in LLT.hints:
size = LLT.hints['getsize']()
MuT = mutype.MuArray(mutype.MU_INT8, size)
return MuT
raise NotImplementedError("don't know how to translate OpaqueType %s" % LLT)
def map_type_funcptr(self, LLT):
LLFnc = LLT.TO
......@@ -351,11 +365,11 @@ class LL2MuMapper:
elif isinstance(llv, CDefinedIntSymbolic):
from rpython.rlib import objectmodel, jit
if llv is objectmodel._translated_to_c:
llv = 1 # faking it to make it work
llv = 1 # faking it to make it work
elif llv is objectmodel.malloc_zero_filled:
llv = 1 # Mu NEW zeros memory
llv = 1 # Mu NEW zeros memory
elif llv is jit._we_are_jitted:
llv = 0 # this is AoT, not jitted
llv = 0 # this is AoT, not jitted
elif 'FinalizerQueue TAG' in llv.expr: # rgc.py:515
llv = 0
else:
......@@ -413,7 +427,7 @@ class LL2MuMapper:
return self.map_value_varstt(llv)
MuT = self.map_type(LLT)
if MuT is mutype.MU_VOID: # empty struct, struct<>
if MuT is mutype.MU_VOID: # empty struct, struct<>
return None
if topstt not in self._topstt_map:
......@@ -491,7 +505,7 @@ class LL2MuMapper:
if isinstance(LLT.TO, lltype.FuncType):
return self.map_value_funcptr(llv)
ref = MuT._null() # set object later
ref = MuT._null() # set object later
self._pending_ptr_values.append((llv._obj, ref))
return ref
......@@ -510,7 +524,7 @@ class LL2MuMapper:
elif isinstance(ref, mutype._muweakref):
ref._obj = weakref.ref(obj)
else:
ref._store(obj) # otherwise (iref, uptr) call _store
ref._store(obj) # otherwise (iref, uptr) call _store
def map_value_funcptr(self, llv):
LLT = lltype.typeOf(llv)
......@@ -555,6 +569,7 @@ class LL2MuMapper:
return layout.mu_offsetOf(MuT, 'length')
else:
raise AssertionError("Value {:r} of type {:r} shouldn't appear.".format(llv, type(llv)))
MuT = self.map_type(lltype.typeOf(llv))
return MuT._val_type(rec(llv))
......@@ -606,7 +621,7 @@ class LL2MuMapper:
if hasattr(self, 'map_op_' + llop.opname):
return getattr(self, 'map_op_' + llop.opname)(llop)
elif llop.opname in _binop_map: # a binop
elif llop.opname in _binop_map: # a binop
if any(cmpop in llop.opname for cmpop in 'lt le eq ne ge gt'.split(' ')):
return self._map_cmpop(llop)
else:
......@@ -697,7 +712,7 @@ class LL2MuMapper:
Constant(MuT._val_type(0), MuT),
llop.args[0],
],
llop.result)
llop.result)
return self.map_op(llop)
map_op_llong_neg = map_op_int_neg
......@@ -828,7 +843,7 @@ class LL2MuMapper:
def _map_convop(self, llop):
return [self.gen_mu_convop(_prim_castop_map[llop.opname],
llop.result.concretetype, llop.args[0], llop.result)]
llop.result.concretetype, llop.args[0], llop.result)]
map_op_cast_int_to_uint = _rename_to_same_as
map_op_cast_uint_to_int = _rename_to_same_as
......@@ -864,21 +879,29 @@ class LL2MuMapper:
ops.append(self.gen_mu_newhybrid(MuT, n_c, llop.result))
else:
assert isinstance(llop.result.concretetype, mutype.MuUPtr)
if MuT == mutype.MU_VOID:
# there are a few places in RPython code (especially libffi, _rawffi)
# that does malloc(rffi.VOIDP.TO, size, flavor='raw').
# In these cases MuT == MU_VOIDP
# Thus directly allocate n_c bytes and return the pointer
ops.extend(self.map_op(SpaceOperation('raw_malloc', [n_c], llop.result)))
return ops
fix = layout.mu_hybsizeOf(MuT, 0)
itm = layout.mu_hybsizeOf(MuT, 1) - fix
# sz = fix + itm * n
v = varof(mutype.MU_INT64)
ops.extend(self.map_op(SpaceOperation('int_mul', [Constant(mutype.mu_int64(itm), mutype.MU_INT64), n_c], v)))
ops.extend(
self.map_op(SpaceOperation('int_mul', [Constant(mutype.mu_int64(itm), mutype.MU_INT64), n_c], v)))
sz = varof(mutype.MU_INT64, 'sz')
ops.extend(self.map_op(SpaceOperation('int_add', [Constant(mutype.mu_int64(fix), mutype.MU_INT64), v], sz)))
ops.extend(self.map_op(SpaceOperation('raw_malloc', [sz], llop.result)))
if 'length' in MuT._names:
ops.extend(self.map_op(SpaceOperation('setfield', [
llop.result, Constant('length', mutype.MU_VOID), n_c
],
varof(mutype.MU_VOID, 'dummy'))))
ops.extend(self.map_op(SpaceOperation(
'setfield', [llop.result, Constant('length', mutype.MU_VOID), n_c],
varof(mutype.MU_VOID, 'dummy'))))
return ops
......@@ -894,7 +917,7 @@ class LL2MuMapper:
iref = var
assert isinstance(MuT.TO, (mutype.MuStruct, mutype.MuHybrid))
idx = MuT.TO._index_of(fldname) # NOTE: may throw AttributeError
idx = MuT.TO._index_of(fldname) # NOTE: may throw AttributeError
iref_fld = varof(cls(getattr(MuT.TO, fldname)), 'irf%s_%s' % (var.name, fldname))
ops.append(self.gen_mu_getfieldiref(iref, fldname, iref_fld))
return iref_fld, ops
......@@ -927,8 +950,8 @@ class LL2MuMapper:
RES_T = llop.result.concretetype.TO
assert isinstance(RES_T, mutype.MuHybrid)
if hasattr(RES_T, 'length'):
iref_fld, ops = self._getfieldiref(var, Constant('length')) # get the length field instead
ops.extend(self.map_op(SpaceOperation('cast_pointer', # cast to correct type
iref_fld, ops = self._getfieldiref(var, Constant('length')) # get the length field instead
ops.extend(self.map_op(SpaceOperation('cast_pointer', # cast to correct type
[Constant(llop.result.concretetype), iref_fld], llop.result)))
else:
iref_fld, ops = self._getinterioriref(var, [fldname_c])
......@@ -966,7 +989,13 @@ class LL2MuMapper:
def map_op_getarrayitem(self, llop):
var, idx_vc = llop.args
iref_itm, ops = self._getarrayitemiref(var, idx_vc)
ops = []
if var.concretetype.TO == mutype.MU_VOID: # cast void* to char*
buf = varof(type(var.concretetype)(self.map_type(rffi.CCHARP).TO))
ops = self.map_op(SpaceOperation('cast_pointer', [var], buf))
var = buf
iref_itm, _ops = self._getarrayitemiref(var, idx_vc)
ops.extend(_ops)
ops.append(self.gen_mu_load(iref_itm, llop.result))
return ops
......@@ -974,9 +1003,22 @@ class LL2MuMapper:
if len(llop.args) < 3:
MuT = llop.args[0].concretetype.TO
assert isinstance(MuT, mutype.MuStruct) and 'Void' in llop.args[0].concretetype.TO._name
return [] # setting Void type values to array of Voids; translate as no-op
return [] # setting Void type values to array of Voids; translate as no-op
var, idx_vc, val_vc = llop.args
iref_itm, ops = self._getarrayitemiref(var, idx_vc)
ops = []
if var.concretetype.TO == mutype.MU_VOID: # cast void* to char*
buf = varof(type(var.concretetype)(self.map_type(rffi.CCHARP).TO))
ops = self.map_op(SpaceOperation('cast_pointer', [var], buf))
var = buf
iref_itm, _ops = self._getarrayitemiref(var, idx_vc)
ops.extend(_ops)
if iref_itm.concretetype.TO != val_vc.concretetype:
if isinstance(iref_itm.concretetype.TO, mutype.MuReferenceType) and \
isinstance(val_vc.concretetype, mutype.MuReferenceType) and \
isinstance(val_vc.concretetype, type(iref_itm.concretetype.TO)):
casted = varof(type(iref_itm.concretetype.TO)(iref_itm.concretetype.TO.TO))
ops.extend(self.map_op(SpaceOperation('cast_pointer', [val_vc], casted)))
val_vc = casted
ops.append(self.gen_mu_store(iref_itm, val_vc, llop.result))
return ops
......@@ -1079,7 +1121,14 @@ class LL2MuMapper:
# TODO: reconsider direct_ptradd and direct_arrayitems, based on the semantic in lltype
def map_op_direct_ptradd(self, llop):
_, ops = self._getarrayitemiref(*llop.args)
var, idx_vc = llop.args
ops = []
if var.concretetype.TO == mutype.MU_VOID: # cast void* to char*
buf = varof(type(var.concretetype)(self.map_type(rffi.CCHARP).TO))
ops = self.map_op(SpaceOperation('cast_pointer', [var], buf))
var = buf
iref_itm, _ops = self._getarrayitemiref(var, idx_vc)
ops.extend(_ops)
ops[-1].result = llop.result
return ops
......@@ -1121,7 +1170,7 @@ class LL2MuMapper:
if llop.result.concretetype == mutype.MU_INT64:
ops.extend(self.map_op(SpaceOperation('int_sub', [adr1_i, adr2_i], llop.result)))
elif isinstance(llop.result.concretetype, mutype.MuUPtr): # not sure if this is ever the case though
elif isinstance(llop.result.concretetype, mutype.MuUPtr): # not sure if this is ever the case though
delta = varof(mutype.MU_INT64)
ops.extend(self.map_op(SpaceOperation('int_sub', [adr1_i, adr2_i], delta)))
ops.append(self.gen_mu_convop('PTRCAST', llop.result.concretetype, delta, llop.result))
......@@ -1215,7 +1264,8 @@ class LL2MuMapper:
return self.map_op_raw_free(llop)
def map_op_raw_memclear(self, llop):
llop.__init__('raw_memset', [llop.args[0], Constant(mutype.mu_int8(0), mutype.MU_INT8), llop.args[1]], llop.result)
llop.__init__('raw_memset', [llop.args[0], Constant(mutype.mu_int8(0), mutype.MU_INT8), llop.args[1]],
llop.result)
return self._map_rawmemop(llop)
def map_op_raw_load(self, llop):
......@@ -1289,7 +1339,7 @@ class LL2MuMapper:
def map_op_cast_ptr_to_int(self, llop):
llop.opname = 'cast_ptr_to_adr'
ops = self.map_op(llop)
if len(ops) == 2: # pinned
if len(ops) == 2: # pinned
ops.extend(self.map_op(SpaceOperation('keepalive', [llop.args[0]], varof(mutype.MU_VOID))))
return ops
......@@ -1308,7 +1358,7 @@ class LL2MuMapper:
if isinstance(SRC, mutype.MuObjectRef) and isinstance(RES, mutype.MuObjectRef):
llop.__init__('cast_pointer', [llop.args[0]], llop.result)
return self.map_op(llop) # does the reference class check in actual mapping function
return self.map_op(llop) # does the reference class check in actual mapping function
elif isinstance(SRC, mutype.MuObjectRef) and isinstance(RES, mutype.MuIntType):
llop.opname = 'cast_ptr_to_adr'
......@@ -1337,7 +1387,7 @@ class LL2MuMapper:
RES_LLT = llop._res_llt
opcode = 'FPTOSI' if is_signed_integer_type(RES_LLT) else 'FPTOUI'
else:
opcode = 'FPTOSI' # by default
opcode = 'FPTOSI' # by default
return [self.gen_mu_convop(opcode, RES, llop.args[0], llop.result)]
elif isinstance(SRC, mutype.MuIntType) and isinstance(RES, mutype.MuFloatType):
......@@ -1345,7 +1395,7 @@ class LL2MuMapper:
SRC_LLT = llop._src_llt
opcode = 'SITOFP' if is_signed_integer_type(SRC_LLT) else 'UITOFP'
else:
opcode = 'SITOFP' # by default
opcode = 'SITOFP' # by default
return [self.gen_mu_convop(opcode, RES, llop.args[0], llop.result)]
elif isinstance(SRC, mutype.MuFloatType) and isinstance(RES, mutype.MuFloatType):
......@@ -1454,7 +1504,8 @@ class LL2MuMapper:
tlref_stt = varof(RefStt)
ops.extend(self.map_op(SpaceOperation('cast_pointer', [tlref_void], tlref_stt)))
fld = llop.args[0].value.expr[10:]
ops.extend(self.map_op(SpaceOperation('setfield', [tlref_stt, Constant(fld, mutype.MU_VOID), llop.args[1]], llop.result)))
ops.extend(self.map_op(
SpaceOperation('setfield', [tlref_stt, Constant(fld, mutype.MU_VOID), llop.args[1]], llop.result)))
return ops
map_op_threadlocalref_get = map_op_threadlocalref_load
......@@ -1531,6 +1582,7 @@ class LL2MuMapper:
MuT = llop.result.concretetype
llop.__init__('same_as', [Constant(MuT._val_type(-1), MuT)], llop.result)
return [llop]
map_op_gc_get_rpy_type_index = map_op_gc_get_rpy_memory_usage
map_op_gc_get_rpy_roots = _same_as_false
......@@ -1556,7 +1608,7 @@ class LL2MuMapper:
assert isinstance(Ref, mutype.MuRef)
Hyb = Ref.TO
assert isinstance(Hyb, mutype.MuHybrid)
assert len(Hyb._names) == 1 # fixed part empty
assert len(Hyb._names) == 1 # fixed part empty
assert Hyb._var_field_type() is mutype.MU_INT8
ops = []
......@@ -1800,7 +1852,7 @@ class LL2MuMapper:
res if res else varof(mutype.MU_VOID))
def gen_mu_ccall(self, callee, args, res=None, keepalive=None, excclause=None,
callconv='DEFAULT'):
callconv='DEFAULT'):
assert isinstance(callee.concretetype, mutype.MuUFuncPtr)
Sig = callee.concretetype.Sig
assert len(args) == len(Sig.ARGS)
......@@ -1834,6 +1886,7 @@ class LL2MuMapper:
return SpaceOperation('mu_comminst', [Constant(inst, mutype.MU_VOID)] + args +
[Constant(metainfo, mutype.MU_VOID)], res)
def varof(TYPE, name=None):
v = Variable(name)
v.concretetype = TYPE
......@@ -1897,7 +1950,7 @@ def _init_binop_map():
'llong': 'int',
'ullong': 'uint',
'lllong': 'int',
'char': 'uint', # it's okay to be a super set of llops
'char': 'uint', # it's okay to be a super set of llops
'unichar': 'uint'
}.items():
for op in "add sub mul floordiv mod and or lshift rshift xor".split(' '):
......@@ -1906,6 +1959,8 @@ def _init_binop_map():
__binop_map['%(org_type)s_%(cmp)s' % locals()] = __binop_map['%(coer_type)s_%(cmp)s' % locals()]
return __binop_map
_binop_map = _init_binop_map()
_prim_castop_map = {
......@@ -1930,6 +1985,7 @@ _prim_castop_map = {
}
from rpython.rlib.rposix import external, ExternalCompilationInfo
c_malloc = external("malloc", [rffi.SIZE_T], rffi.VOIDP, _nowrapper=True)
c_free = external("free", [rffi.VOIDP], lltype.Void, _nowrapper=True)
c_memcpy = external("memcpy", [rffi.VOIDP, rffi.VOIDP, rffi.SIZE_T], lltype.Void, _nowrapper=True)
......@@ -1945,6 +2001,7 @@ _llrawop_c_externfncs = {
_llrawop_c_externfncs['memcopy'] = _llrawop_c_externfncs['memcpy']
from rpython.translator import cdir
debug_eci = ExternalCompilationInfo(includes=['src/debug_print.h', 'src/profiling.h'],
include_dirs=[cdir],
post_include_bits=['#define HAVE_DEBUG_PRINTS() (pypy_have_debug_prints & 1)'],
......@@ -1991,7 +2048,7 @@ def get_typedescr_str(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.MuFuncRef: 'r', # assuming function ref/uptr has same size as ref/uptr
mutype.MuUFuncPtr: 'p',
mutype.MU_INT8: 'b',
mutype.MU_INT16: 's',
......@@ -2011,4 +2068,4 @@ def get_typedescr_str(MuT): # JIT Mu back-end support
var = get_typedescr_str(MuT._vartype.OF)
return '{%(fix)s|%(var)s}' % locals()
if isinstance(MuT, mutype.MuArray):
return '[%d|%s]' % (MuT.length, get_typedescr_str(MuT.OF))
\ No newline at end of file
return '[%d|%s]' % (MuT.length, get_typedescr_str(MuT.OF))
......@@ -44,6 +44,12 @@ def test_map_type_opqptr():
LL_META_CSTR = lltype.Ptr(lltype.GcOpaqueType("MuStr", hints={'mu_render_ptr_as': mutype.META_CSTR}))
assert ll2mu.map_type(LL_META_CSTR) == mutype.META_CSTR
# other opaque types
# try translate the underlying opaque type first
from rpython.rlib._rsocket_rffi import fd_set
assert ll2mu.map_type(fd_set) == mutype.MuUPtr(mutype.MuArray(mutype.MU_INT8, fd_set.TO.hints['getsize']()))
def test_map_type_hybrid():
ll2mu = LL2MuMapper()
from rpython.rtyper.lltypesystem.rstr import STR
......@@ -727,3 +733,4 @@ def test_map_op_mu_meta_lst2carr():
muops = ll2mu.map_op(llop)
assert [op.opname for op in muops] == ['mu_getiref', 'mu_getfieldiref', 'mu_load',
'mu_getiref', 'mu_getvarpartiref', 'mu_shiftiref']
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment