[pypy-commit] pypy stm-gc: Start to refactor transform.py.
arigo
noreply at buildbot.pypy.org
Thu Feb 16 16:48:39 CET 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: stm-gc
Changeset: r52551:276616f00df5
Date: 2012-02-16 16:48 +0100
http://bitbucket.org/pypy/pypy/changeset/276616f00df5/
Log: Start to refactor transform.py.
diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py
--- a/pypy/translator/c/genc.py
+++ b/pypy/translator/c/genc.py
@@ -136,7 +136,6 @@
from pypy.translator.stm import transform
transformer = transform.STMTransformer(self.translator)
transformer.transform()
- log.info("Software Transactional Memory transformation applied")
gcpolicyclass = self.get_gcpolicyclass()
diff --git a/pypy/translator/stm/transform.py b/pypy/translator/stm/transform.py
--- a/pypy/translator/stm/transform.py
+++ b/pypy/translator/stm/transform.py
@@ -2,6 +2,7 @@
from pypy.objspace.flow.model import Block, Link, checkgraph
from pypy.annotation import model as annmodel
from pypy.translator.unsimplify import varoftype, copyvar
+from pypy.translator.stm.localtracker import StmLocalTracker
from pypy.rpython.lltypesystem import lltype, lloperation
from pypy.rpython import rclass
@@ -9,7 +10,7 @@
ALWAYS_ALLOW_OPERATIONS = set([
'direct_call', 'force_cast', 'keepalive', 'cast_ptr_to_adr',
'debug_print', 'debug_assert', 'cast_opaque_ptr', 'hint',
- 'indirect_call', 'stack_current',
+ 'indirect_call', 'stack_current', 'gc_stack_bottom',
])
ALWAYS_ALLOW_OPERATIONS |= set(lloperation.enum_tryfold_ops())
@@ -23,27 +24,42 @@
def __init__(self, translator=None):
self.translator = translator
+ self.count_get_local = 0
+ self.count_get_nonlocal = 0
+ self.count_get_immutable = 0
+ self.count_set_local = 0
+ self.count_set_nonlocal = 0
+ self.count_set_immutable = 0
- def transform(self): ##, entrypointptr):
+ def transform(self):
assert not hasattr(self.translator, 'stm_transformation_applied')
-## entrypointgraph = entrypointptr._obj.graph
+ self.start_log()
+ self.localtracker = StmLocalTracker(self.translator)
for graph in self.translator.graphs:
-## self.seen_transaction_boundary = False
-## self.seen_gc_stack_bottom = False
self.transform_graph(graph)
-## if self.seen_transaction_boundary:
-## self.add_stm_declare_variable(graph)
-## if self.seen_gc_stack_bottom:
-## self.add_descriptor_init_stuff(graph)
-## self.add_descriptor_init_stuff(entrypointgraph, main=True)
+ self.localtracker = None
self.translator.stm_transformation_applied = True
+ self.print_logs()
+
+ def start_log(self):
+ from pypy.translator.c.support import log
+ log.info("Software Transactional Memory transformation")
+
+ def print_logs(self):
+ from pypy.translator.c.support import log
+ log('get*: proven local: %d' % self.count_get_local)
+ log(' not proven local: %d' % self.count_get_nonlocal)
+ log(' immutable: %d' % self.count_get_immutable)
+ log('set*: proven local: %d' % self.count_set_local)
+ log(' not proven local: %d' % self.count_set_nonlocal)
+ log(' immutable: %d' % self.count_set_immutable)
+ log.info("Software Transactional Memory transformation applied")
def transform_block(self, block):
if block.operations == ():
return
newoperations = []
self.current_block = block
- #self.access_directly = set()
for i, op in enumerate(block.operations):
self.current_op_index = i
try:
@@ -56,199 +72,105 @@
meth = turn_inevitable_and_proceed
setattr(self.__class__, 'stt_' + op.opname,
staticmethod(meth))
- res = meth(newoperations, op)
- if res is True:
- newoperations.append(op)
- elif res is False:
- turn_inevitable_and_proceed(newoperations, op)
- else:
- assert res is None
+ meth(newoperations, op)
block.operations = newoperations
self.current_block = None
- #self.access_directly = None
def transform_graph(self, graph):
for block in graph.iterblocks():
self.transform_block(block)
-## def add_descriptor_init_stuff(self, graph, main=False):
-## if main:
-## self._add_calls_around(graph,
-## _rffi_stm.begin_inevitable_transaction,
-## _rffi_stm.commit_transaction)
-## self._add_calls_around(graph,
-## _rffi_stm.descriptor_init,
-## _rffi_stm.descriptor_done)
-
-## def _add_calls_around(self, graph, f_init, f_done):
-## c_init = Constant(f_init, lltype.typeOf(f_init))
-## c_done = Constant(f_done, lltype.typeOf(f_done))
-## #
-## block = graph.startblock
-## v = varoftype(lltype.Void)
-## op = SpaceOperation('direct_call', [c_init], v)
-## block.operations.insert(0, op)
-## #
-## v = copyvar(self.translator.annotator, graph.getreturnvar())
-## extrablock = Block([v])
-## v_none = varoftype(lltype.Void)
-## newop = SpaceOperation('direct_call', [c_done], v_none)
-## extrablock.operations = [newop]
-## extrablock.closeblock(Link([v], graph.returnblock))
-## for block in graph.iterblocks():
-## if block is not extrablock:
-## for link in block.exits:
-## if link.target is graph.returnblock:
-## link.target = extrablock
-## checkgraph(graph)
-
-## def add_stm_declare_variable(self, graph):
-## block = graph.startblock
-## v = varoftype(lltype.Void)
-## op = SpaceOperation('stm_declare_variable', [], v)
-## block.operations.insert(0, op)
-
# ----------
- def stt_getfield(self, newoperations, op):
- STRUCT = op.args[0].concretetype.TO
+ def transform_get(self, newoperations, op, stmopname, immutable=False):
if op.result.concretetype is lltype.Void:
- op1 = op
- elif STRUCT._immutable_field(op.args[1].value):
- op1 = op
- elif 'stm_access_directly' in STRUCT._hints:
- #try:
- # immfld = STRUCT._hints['immutable_fields']
- #except KeyError:
- # pass
- #else:
- # rank = immfld._fields.get(op.args[1].value, None)
- # if rank is rclass.IR_MUTABLE_OWNED:
- # self.access_directly.add(op.result)
- op1 = op
- elif STRUCT._gckind == 'raw':
- turn_inevitable(newoperations, "getfield-raw")
- op1 = op
- else:
- op1 = SpaceOperation('stm_getfield', op.args, op.result)
+ newoperations.append(op)
+ return
+ if op.args[0].concretetype.TO._gckind == 'raw':
+ turn_inevitable(newoperations, op.opname + '-raw')
+ newoperations.append(op)
+ return
+ if immutable:
+ self.count_get_immutable += 1
+ newoperations.append(op)
+ return
+ if isinstance(op.args[0], Variable):
+ if self.localtracker.is_local(op.args[0]):
+ self.count_get_local += 1
+ newoperations.append(op)
+ return
+ self.count_get_nonlocal += 1
+ op1 = SpaceOperation(stmopname, op.args, op.result)
newoperations.append(op1)
- def with_writebarrier(self, newoperations, op):
+ def transform_set(self, newoperations, op, immutable=False):
+ if op.args[-1].concretetype is lltype.Void:
+ newoperations.append(op)
+ return
+ if op.args[0].concretetype.TO._gckind == 'raw':
+ turn_inevitable(newoperations, op.opname + '-raw')
+ newoperations.append(op)
+ return
+ if immutable:
+ self.count_set_immutable += 1
+ newoperations.append(op)
+ return
+ if isinstance(op.args[0], Variable):
+ if self.localtracker.is_local(op.args[0]):
+ self.count_set_local += 1
+ newoperations.append(op)
+ return
+ self.count_set_nonlocal += 1
v_arg = op.args[0]
v_local = varoftype(v_arg.concretetype)
op0 = SpaceOperation('stm_writebarrier', [v_arg], v_local)
newoperations.append(op0)
op1 = SpaceOperation('bare_' + op.opname, [v_local] + op.args[1:],
op.result)
- return op1
+ newoperations.append(op1)
+
+
+ def stt_getfield(self, newoperations, op):
+ STRUCT = op.args[0].concretetype.TO
+ immutable = STRUCT._immutable_field(op.args[1].value)
+ self.transform_get(newoperations, op, 'stm_getfield', immutable)
def stt_setfield(self, newoperations, op):
STRUCT = op.args[0].concretetype.TO
- if op.args[2].concretetype is lltype.Void:
- op1 = op
- elif (STRUCT._immutable_field(op.args[1].value) or
- 'stm_access_directly' in STRUCT._hints):
- op1 = op
- elif STRUCT._gckind == 'raw':
- turn_inevitable(newoperations, "setfield-raw")
- op1 = op
- else:
- op1 = self.with_writebarrier(newoperations, op)
- newoperations.append(op1)
+ immutable = STRUCT._immutable_field(op.args[1].value)
+ self.transform_set(newoperations, op, immutable)
def stt_getarrayitem(self, newoperations, op):
ARRAY = op.args[0].concretetype.TO
- if op.result.concretetype is lltype.Void:
- op1 = op
- elif ARRAY._immutable_field():
- op1 = op
- #elif op.args[0] in self.access_directly:
- # op1 = op
- elif ARRAY._gckind == 'raw':
- turn_inevitable(newoperations, "getarrayitem-raw")
- op1 = op
- else:
- op1 = SpaceOperation('stm_getarrayitem', op.args, op.result)
- newoperations.append(op1)
+ immutable = ARRAY._immutable_field()
+ self.transform_get(newoperations, op, 'stm_getarrayitem', immutable)
def stt_setarrayitem(self, newoperations, op):
ARRAY = op.args[0].concretetype.TO
- if op.args[2].concretetype is lltype.Void:
- op1 = op
- elif ARRAY._immutable_field():
- op1 = op
- #elif op.args[0] in self.access_directly:
- # op1 = op
- elif ARRAY._gckind == 'raw':
- turn_inevitable(newoperations, "setarrayitem-raw")
- op1 = op
- else:
- op1 = self.with_writebarrier(newoperations, op)
- newoperations.append(op1)
+ immutable = ARRAY._immutable_field()
+ self.transform_set(newoperations, op, immutable)
def stt_getinteriorfield(self, newoperations, op):
OUTER = op.args[0].concretetype.TO
- if op.result.concretetype is lltype.Void:
- op1 = op
- elif OUTER._immutable_interiorfield(unwraplist(op.args[1:])):
- op1 = op
- elif OUTER._gckind == 'raw':
- turn_inevitable(newoperations, "getinteriorfield-raw")
- op1 = op
- else:
- op1 = SpaceOperation('stm_getinteriorfield', op.args, op.result)
- newoperations.append(op1)
+ immutable = OUTER._immutable_interiorfield(unwraplist(op.args[1:]))
+ self.transform_get(newoperations, op, 'stm_getinteriorfield',immutable)
def stt_setinteriorfield(self, newoperations, op):
OUTER = op.args[0].concretetype.TO
- if op.args[-1].concretetype is lltype.Void:
- op1 = op
- elif OUTER._immutable_interiorfield(unwraplist(op.args[1:-1])):
- op1 = op
- elif OUTER._gckind == 'raw':
- turn_inevitable(newoperations, "setinteriorfield-raw")
- op1 = op
- else:
- op1 = self.with_writebarrier(newoperations, op)
- newoperations.append(op1)
-
-## def stt_stm_transaction_boundary(self, newoperations, op):
-## self.seen_transaction_boundary = True
-## v_result = op.result
-## # record in op.args the list of variables that are alive across
-## # this call
-## block = self.current_block
-## vars = set()
-## for op in block.operations[:self.current_op_index:-1]:
-## vars.discard(op.result)
-## vars.update(op.args)
-## for link in block.exits:
-## vars.update(link.args)
-## vars.update(link.getextravars())
-## livevars = [v for v in vars if isinstance(v, Variable)]
-## newop = SpaceOperation('stm_transaction_boundary', livevars, v_result)
-## newoperations.append(newop)
+ immutable = OUTER._immutable_interiorfield(unwraplist(op.args[1:-1]))
+ self.transform_set(newoperations, op, immutable)
def stt_malloc(self, newoperations, op):
flags = op.args[1].value
- return flags['flavor'] == 'gc'
-
- def stt_malloc_varsize(self, newoperations, op):
- flags = op.args[1].value
- return flags['flavor'] == 'gc'
-
- stt_malloc_nonmovable = stt_malloc
-
- def stt_gc_stack_bottom(self, newoperations, op):
-## self.seen_gc_stack_bottom = True
+ if flags['flavor'] == 'gc':
+ assert self.localtracker.is_local(op.result)
+ else:
+ turn_inevitable(newoperations, 'malloc-raw')
newoperations.append(op)
- #def stt_same_as(self, newoperations, op):
- # if op.args[0] in self.access_directly:
- # self.access_directly.add(op.result)
- # newoperations.append(op)
- #
- #stt_cast_pointer = stt_same_as
+ stt_malloc_varsize = stt_malloc
+ stt_malloc_nonmovable = stt_malloc
+ stt_malloc_nonmovable_varsize = stt_malloc
def transform_graph(graph):
More information about the pypy-commit
mailing list