[pypy-svn] r32145 - in pypy/dist/pypy: rpython/memory translator/llvm translator/llvm/module
arigo at codespeak.net
arigo at codespeak.net
Mon Sep 11 13:58:08 CEST 2006
Author: arigo
Date: Mon Sep 11 13:58:06 2006
New Revision: 32145
Modified:
pypy/dist/pypy/rpython/memory/gctransform.py
pypy/dist/pypy/translator/llvm/database.py
pypy/dist/pypy/translator/llvm/gc.py
pypy/dist/pypy/translator/llvm/module/genexterns.c
pypy/dist/pypy/translator/llvm/opwriter.py
pypy/dist/pypy/translator/llvm/structnode.py
Log:
Started support for --gc=framework in llvm. Cleaned up and support more
address and offset features. Always do raisingop2direct_call in the graphs
produced by the GC (because they come after the normal backend_optimize() has
been called).
Now we die in llvm's own optimizers in a failed assertion. Hard to test our
code now :-((( It's known to be incomplete, though.
Modified: pypy/dist/pypy/rpython/memory/gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform.py (original)
+++ pypy/dist/pypy/rpython/memory/gctransform.py Mon Sep 11 13:58:06 2006
@@ -947,7 +947,7 @@
annmodel.s_None)
annhelper.finish() # at this point, annotate all mix-level helpers
- annhelper.backend_optimize()
+ annhelper.backend_optimize(raisingop2direct_call_all=True)
self.collect_analyzer = CollectAnalyzer(self.translator)
self.collect_analyzer.analyze_all()
Modified: pypy/dist/pypy/translator/llvm/database.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/database.py (original)
+++ pypy/dist/pypy/translator/llvm/database.py Mon Sep 11 13:58:06 2006
@@ -144,6 +144,11 @@
def prepare_constant(self, type_, value):
if isinstance(type_, lltype.Primitive):
#log.prepareconstant(value, "(is primitive)")
+ if type_ is llmemory.Address:
+ # prepare the constant data which this address references
+ assert isinstance(value, llmemory.fakeaddress)
+ if value.ob is not None:
+ self.prepare_constant(lltype.typeOf(value.ob), value.ob)
return
if isinstance(type_, lltype.Ptr):
@@ -229,10 +234,10 @@
return self.primitives.repr(arg.concretetype, arg.value)
else:
assert isinstance(arg.value, lltype._ptr)
- node = self.obj2node.get(arg.value._obj)
- if node is None:
+ if not arg.value:
return 'null'
else:
+ node = self.obj2node[arg.value._obj]
return node.get_ref()
else:
assert isinstance(arg, Variable)
@@ -405,9 +410,11 @@
def repr(self, type_, value):
try:
- return self.reprs[type_](type_, value)
+ reprfn = self.reprs[type_]
except KeyError:
raise Exception, "unsupported primitive type %r, value %r" % (type_, value)
+ else:
+ return reprfn(type_, value)
def repr_default(self, type_, value):
return str(value)
@@ -461,14 +468,22 @@
from_, indices, to = self.get_offset(value.offset)
indices_as_str = ", ".join("%s %s" % (w, i) for w, i in indices)
- original_typename = self.database.repr_type(from_)
- orignal_ref = self.database.repr_name(value.ob._obj)
+ #original_typename = self.database.repr_type(from_)
+ #orignal_ref = self.database.repr_name(value.ob._obj)
+ #
+ #typename = self.database.repr_type(to)
+ #ref = "getelementptr(%s* %s, %s)" % (original_typename,
+ # orignal_ref,
+ # indices_as_str)
+
+ ptrtype = self.database.repr_type(lltype.Ptr(from_))
+ node = self.database.obj2node[value.ob._obj]
+ parentref = node.get_pbcref(ptrtype)
typename = self.database.repr_type(to)
- ref = "getelementptr(%s* %s, %s)" % (original_typename,
- orignal_ref,
- indices_as_str)
-
+ ref = "getelementptr(%s %s, %s)" % (ptrtype, parentref,
+ indices_as_str)
+
res = "cast(%s* %s to sbyte*)" % (typename, ref)
return res
@@ -506,42 +521,46 @@
return repr
- def get_offset(self, value, fromoffset=False):
+ def get_offset(self, value, initialindices=None):
" return (from_type, (indices, ...), to_type) "
word = self.database.get_machine_word()
uword = self.database.get_machine_uword()
- indices = []
+ indices = initialindices or [(word, 0)]
if isinstance(value, llmemory.ItemOffset):
# skips over a fixed size item (eg array access)
from_ = value.TYPE
- indices.append((word, value.repeat))
+ lasttype, lastvalue = indices[-1]
+ assert lasttype == word
+ indices[-1] = (word, lastvalue + value.repeat)
to = value.TYPE
elif isinstance(value, llmemory.FieldOffset):
# jumps to a field position in a struct
from_ = value.TYPE
pos = getindexhelper(value.fldname, value.TYPE)
- if not fromoffset:
- indices.append((word, 0))
indices.append((uword, pos))
to = getattr(value.TYPE, value.fldname)
-
+
+ elif isinstance(value, llmemory.ArrayLengthOffset):
+ # jumps to the place where the array length is stored
+ from_ = value.TYPE # <Array of T> or <GcArray of T>
+ assert isinstance(value.TYPE, lltype.Array)
+ indices.append((uword, 0))
+ to = lltype.Signed
+
elif isinstance(value, llmemory.ArrayItemsOffset):
# jumps to the beginning of array area
from_ = value.TYPE
- if not fromoffset:
- indices.append((word, 0))
if not isinstance(value.TYPE, lltype.FixedSizeArray):
indices.append((uword, 1))
+ indices.append((word, 0)) # go to the 1st item
to = value.TYPE.OF
elif isinstance(value, llmemory.CompositeOffset):
- from_, indices, to = self.get_offset(value.offsets[0])
- indices = list(indices)
+ from_, indices, to = self.get_offset(value.offsets[0], indices)
for item in value.offsets[1:]:
- _, more, to = self.get_offset(item, fromoffset=True)
- indices.extend(more)
+ _, indices, to = self.get_offset(item, indices)
else:
raise Exception("unsupported offset")
Modified: pypy/dist/pypy/translator/llvm/gc.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/gc.py (original)
+++ pypy/dist/pypy/translator/llvm/gc.py Mon Sep 11 13:58:06 2006
@@ -119,6 +119,8 @@
gcpolicy = RefcountingGcPolicy(db)
elif gcpolicy in ('none', 'raw'):
gcpolicy = RawGcPolicy(db)
+ elif gcpolicy == 'framework':
+ gcpolicy = FrameworkGcPolicy(db)
else:
raise Exception, 'unknown gcpolicy: ' + str(gcpolicy)
return gcpolicy
@@ -186,10 +188,14 @@
uword = self.db.get_machine_uword()
fnname = '%pypy_malloc' + (atomic and '_atomic' or '')
- if self.exc_useringbuf and exc_flag:
- fnname += '_ringbuffer'
- # dont clear the ringbuffer data
- atomic = False
+
+## XXX (arigo) disabled the ring buffer for comparison purposes
+## XXX until we know if it's a valid optimization or not
+
+## if self.exc_useringbuf and exc_flag:
+## fnname += '_ringbuffer'
+## # dont clear the ringbuffer data
+## atomic = False
# malloc_size is unsigned right now
sizei = '%malloc_sizei' + self.get_count()
@@ -218,3 +224,19 @@
def op_free(self, codewriter, opr):
assert opr.rettype == 'void' and len(opr.argtypes) == 1
codewriter.free(opr.argtypes[0], opr.argrefs[0])
+
+class FrameworkGcPolicy(GcPolicy):
+
+ def __init__(self, db):
+ self.db = db
+
+ def genextern_code(self):
+ # XXX
+ # This is not finished: we must call the gc init function!
+ r = ''
+ r += '#define __GC_STARTUP_CODE__\n'
+ r += '#define __GC_SETUP_CODE__\n'
+ return r
+
+ def gc_libraries(self):
+ return ['pthread']
Modified: pypy/dist/pypy/translator/llvm/module/genexterns.c
==============================================================================
--- pypy/dist/pypy/translator/llvm/module/genexterns.c (original)
+++ pypy/dist/pypy/translator/llvm/module/genexterns.c Mon Sep 11 13:58:06 2006
@@ -37,6 +37,10 @@
memcpy((void *) ptr2, (void *) ptr1, size);
}
+void raw_memclear(void* ptr, long size) {
+ memset(ptr, 0, size);
+}
+
char *LLVM_RPython_StartupCode();
char *RPython_StartupCode() {
Modified: pypy/dist/pypy/translator/llvm/opwriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/opwriter.py (original)
+++ pypy/dist/pypy/translator/llvm/opwriter.py Mon Sep 11 13:58:06 2006
@@ -359,6 +359,8 @@
self.codewriter.store(opr.argtypes[2], opr.argrefs[2], tmpvar)
else:
self._skipped(opr)
+
+ bare_setfield = setfield
def getarrayitem(self, opr):
if opr.rettype == "void":
@@ -451,6 +453,10 @@
self.codewriter.call(opr.retref, opr.rettype, "%raw_malloc",
opr.argtypes, opr.argrefs)
+ def raw_malloc_usage(self, opr):
+ self.codewriter.cast(opr.retref, opr.argtypes[0], opr.argrefs[0],
+ opr.rettype)
+
def raw_free(self, opr):
self.codewriter.call(opr.retref, opr.rettype, "%raw_free",
opr.argtypes, opr.argrefs)
@@ -459,6 +465,10 @@
self.codewriter.call(opr.retref, opr.rettype, "%raw_memcopy",
opr.argtypes, opr.argrefs)
+ def raw_memclear(self, opr):
+ self.codewriter.call(opr.retref, opr.rettype, "%raw_memclear",
+ opr.argtypes, opr.argrefs)
+
def raw_store(self, opr):
arg_addr, arg_dummy, arg_incr, arg_value = opr.argrefs
(argtype_addr, argtype_dummy,
@@ -503,3 +513,6 @@
cast_addr = incr_addr
self.codewriter.load(opr.retref, opr.rettype, cast_addr)
+
+ def debug_print(self, opr):
+ pass # XXX
Modified: pypy/dist/pypy/translator/llvm/structnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/structnode.py (original)
+++ pypy/dist/pypy/translator/llvm/structnode.py Mon Sep 11 13:58:06 2006
@@ -259,6 +259,7 @@
found = True
break
pos += 1
+ assert found
ref = "getelementptr(%s* %s, int 0, uint %s)" %(
self.get_typerepr(),
More information about the Pypy-commit
mailing list