[pypy-svn] r65541 - pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli
antocuni at codespeak.net
antocuni at codespeak.net
Tue Jun 2 14:02:15 CEST 2009
Author: antocuni
Date: Tue Jun 2 14:02:14 2009
New Revision: 65541
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/method.py
Log:
add the "nocast" option, to avoid unneeded casts when doing {get,set}field_gc:
so far boxes were stored with type System.Object, as they needed to be casted
before accessing the fields. With "nocast", we skim over all operations to
compute the exact type to store the variable without needing to do any cast.
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/method.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/method.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/method.py Tue Jun 2 14:02:14 2009
@@ -36,7 +36,10 @@
class __extend__(AbstractValue):
__metaclass__ = extendabletype
- def getCliType(self):
+ def getCliType(self, meth):
+ if self in meth.box2type:
+ return meth.box2type[self]
+
if self.type == history.INT:
return dotnet.typeof(System.Int32)
elif self.type == history.OBJ:
@@ -104,7 +107,7 @@
self.index = index
self.cliType = cliType
- def getCliType(self):
+ def getCliType(self, meth):
return self.cliType
def load(self, meth):
@@ -129,8 +132,9 @@
class Method(object):
operations = [] # overwritten at the end of the module
- tailcall = True
debug = False
+ tailcall = True
+ nocast = True
def __init__(self, cpu, name, loop):
self.setoptions()
@@ -159,6 +163,9 @@
logger.eventually_log_operations(loop.inputargs, loop.operations, None,
compute_unique_id(loop))
# ----
+ self.box2type = {}
+ if self.nocast:
+ self.compute_types()
self.emit_load_inputargs()
self.emit_preamble()
self.emit_operations(loop.operations)
@@ -179,17 +186,38 @@
def setoptions(self):
opts = os.environ.get('PYPYJITOPT')
if opts is None:
- pass
- parts = opts.split()
+ return
+ parts = opts.split(' ')
for part in parts:
name, value = self._parseopt(part)
if name == 'debug':
self.debug = value
elif name == 'tailcall':
self.tailcall = value
+ elif name == 'nocast':
+ self.nocast = value
else:
os.write(2, 'Warning: invalid option name: %s\n' % name)
+ def compute_types(self):
+ # XXX: look also in op.suboperations
+ box2classes = {} # box --> [ootype.Class]
+ for op in self.loop.operations:
+ if op.opnum in (rop.GETFIELD_GC, rop.SETFIELD_GC):
+ box = op.args[0]
+ descr = op.descr
+ assert isinstance(descr, runner.FieldDescr)
+ box2classes.setdefault(box, []).append(descr.selfclass)
+
+ for box, classes in box2classes.iteritems():
+ cls = classes[0]
+ for cls2 in classes[1:]:
+ if ootype.subclassof(cls, cls2):
+ cls = cls2
+ else:
+ assert ootype.subclassof(cls2, cls)
+ self.box2type[box] = dotnet.class2type(cls)
+
def finish_code(self):
delegatetype = dotnet.typeof(LoopDelegate)
# initialize the array of genconsts
@@ -218,7 +246,7 @@
try:
return self.boxes[box]
except KeyError:
- v = self.il.DeclareLocal(box.getCliType())
+ v = self.il.DeclareLocal(box.getCliType(self))
self.boxes[box] = v
return v
@@ -275,7 +303,7 @@
self.emit_debug("executing: " + self.name)
i = 0
for box in self.loop.inputargs:
- self.load_inputarg(i, box.type, box.getCliType())
+ self.load_inputarg(i, box.type, box.getCliType(self))
box.store(self)
i+=1
@@ -366,7 +394,7 @@
# store the latest values
i = 0
for box in op.args:
- self.store_inputarg(i, box.type, box.getCliType(), box)
+ self.store_inputarg(i, box.type, box.getCliType(self), box)
i+=1
def emit_guard_bool(self, op, opcode):
@@ -508,8 +536,10 @@
assert isinstance(descr, runner.FieldDescr)
clitype = descr.get_self_clitype()
fieldinfo = descr.get_field_info()
- op.args[0].load(self)
- self.il.Emit(OpCodes.Castclass, clitype)
+ obj = op.args[0]
+ obj.load(self)
+ if obj.getCliType(self) is not clitype:
+ self.il.Emit(OpCodes.Castclass, clitype)
self.il.Emit(OpCodes.Ldfld, fieldinfo)
self.store_result(op)
@@ -520,8 +550,10 @@
assert isinstance(descr, runner.FieldDescr)
clitype = descr.get_self_clitype()
fieldinfo = descr.get_field_info()
- op.args[0].load(self)
- self.il.Emit(OpCodes.Castclass, clitype)
+ obj = op.args[0]
+ obj.load(self)
+ if obj.getCliType(self) is not clitype:
+ self.il.Emit(OpCodes.Castclass, clitype)
op.args[1].load(self)
self.il.Emit(OpCodes.Stfld, fieldinfo)
More information about the Pypy-commit
mailing list