[pypy-svn] pypy jit-short_from_state: moved VirtualState handling into file of its own separating it (more or less) from the resume handling
hakanardo
commits-noreply at bitbucket.org
Tue Mar 29 08:19:17 CEST 2011
Author: Hakan Ardo <hakan at debian.org>
Branch: jit-short_from_state
Changeset: r43000:936aa44d46f9
Date: 2011-03-29 08:18 +0200
http://bitbucket.org/pypy/pypy/changeset/936aa44d46f9/
Log: moved VirtualState handling into file of its own separating it (more
or less) from the resume handling
diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py
--- a/pypy/jit/metainterp/optimizeopt/unroll.py
+++ b/pypy/jit/metainterp/optimizeopt/unroll.py
@@ -1,5 +1,5 @@
from pypy.jit.metainterp.optimizeopt.optimizer import *
-from pypy.jit.metainterp.optimizeopt.virtualize import AbstractVirtualValue
+from pypy.jit.metainterp.optimizeopt.virtualstate import VirtualStateAdder
from pypy.jit.metainterp.resoperation import rop, ResOperation
from pypy.jit.metainterp.compile import ResumeGuardDescr
from pypy.jit.metainterp.resume import Snapshot
@@ -128,131 +128,6 @@
self.snapshot_map[snapshot] = new_snapshot
return new_snapshot
-class VirtualState(object):
- def __init__(self, state):
- self.state = state
-
- def generalization_of(self, other):
- assert len(self.state) == len(other.state)
- for i in range(len(self.state)):
- if not self.state[i].generalization_of(other.state[i]):
- return False
- return True
-
- def generate_guards(self, other, args, cpu, extra_guards):
- assert len(self.state) == len(other.state) == len(args)
- for i in range(len(self.state)):
- self.state[i].generate_guards(other.state[i], args[i],
- cpu, extra_guards)
-
- def make_inputargs(self, values):
- assert len(values) == len(self.state)
- inputargs = []
- seen_inputargs = {}
- for i in range(len(values)):
- self.state[i].enum_forced_boxes(inputargs, seen_inputargs,
- values[i])
- return inputargs
-
-
-class VirtualStateAdder(resume.ResumeDataVirtualAdder):
- def __init__(self, optimizer):
- self.fieldboxes = {}
- self.optimizer = optimizer
- self.info = {}
-
- def register_virtual_fields(self, keybox, fieldboxes):
- self.fieldboxes[keybox] = fieldboxes
-
- def already_seen_virtual(self, keybox):
- return keybox in self.fieldboxes
-
- def getvalue(self, box):
- return self.optimizer.getvalue(box)
-
- def state(self, box):
- value = self.getvalue(box)
- box = value.get_key_box()
- try:
- info = self.info[box]
- except KeyError:
- if value.is_virtual():
- self.info[box] = info = value.make_virtual_info(self, None)
- flds = self.fieldboxes[box]
- info.fieldstate = [self.state(b) for b in flds]
- else:
- self.info[box] = info = self.make_not_virtual(value)
- return info
-
- def get_virtual_state(self, jump_args):
- for box in jump_args:
- value = self.getvalue(box)
- value.get_args_for_fail(self)
- return VirtualState([self.state(box) for box in jump_args])
-
-
- def make_not_virtual(self, value):
- return NotVirtualInfo(value)
-
-class NotVirtualInfo(resume.AbstractVirtualInfo):
- def __init__(self, value):
- self.known_class = value.known_class
- self.level = value.level
- if value.intbound is None:
- self.intbound = IntBound(MININT, MAXINT)
- else:
- self.intbound = value.intbound.clone()
- if value.is_constant():
- self.constbox = value.box
- else:
- self.constbox = None
-
- def generalization_of(self, other):
- # XXX This will always retrace instead of forcing anything which
- # might be what we want sometimes?
- if not isinstance(other, NotVirtualInfo):
- return False
- if other.level < self.level:
- return False
- if self.level == LEVEL_CONSTANT:
- if not self.constbox.same_constant(other.constbox):
- return False
- elif self.level == LEVEL_KNOWNCLASS:
- if self.known_class != other.known_class: # FIXME: use issubclass?
- return False
- return self.intbound.contains_bound(other.intbound)
-
- def _generate_guards(self, other, box, cpu, extra_guards):
- if not isinstance(other, NotVirtualInfo):
- raise InvalidLoop
- if self.level == LEVEL_KNOWNCLASS and \
- box.nonnull() and \
- self.known_class.same_constant(cpu.ts.cls_of_box(box)):
- # Note: This is only a hint on what the class of box was
- # during the trace. There are actually no guarentees that this
- # box realy comes from a trace. The hint is used here to choose
- # between either eimtting a guard_class and jumping to an
- # excisting compiled loop or retracing the loop. Both
- # alternatives will always generate correct behaviour, but
- # performace will differ.
- op = ResOperation(rop.GUARD_CLASS, [box, self.known_class], None)
- extra_guards.append(op)
- return
- # Remaining cases are probably not interesting
- raise InvalidLoop
- if self.level == LEVEL_CONSTANT:
- import pdb; pdb.set_trace()
- raise NotImplementedError
-
- def enum_forced_boxes(self, boxes, already_seen, value):
- if self.level == LEVEL_CONSTANT:
- return
- key = value.get_key_box()
- if key not in already_seen:
- boxes.append(value.force_box())
- already_seen[value.get_key_box()] = None
-
-
class UnrollOptimizer(Optimization):
"""Unroll the loop into two iterations. The first one will
become the preamble or entry bridge (don't think there is a
diff --git a/pypy/jit/metainterp/resume.py b/pypy/jit/metainterp/resume.py
--- a/pypy/jit/metainterp/resume.py
+++ b/pypy/jit/metainterp/resume.py
@@ -434,20 +434,6 @@
def debug_prints(self):
raise NotImplementedError
-
- def generalization_of(self, other):
- raise NotImplementedError
-
- def generate_guards(self, other, box, cpu, extra_guards):
- if self.generalization_of(other):
- return
- self._generate_guards(other, box, cpu, extra_guards)
-
- def _generate_guards(self, other, box, cpu, extra_guards):
- raise InvalidLoop
-
- def enum_forced_boxes(self, boxes, already_seen, value):
- raise NotImplementedError
class AbstractVirtualStructInfo(AbstractVirtualInfo):
def __init__(self, fielddescrs):
@@ -468,39 +454,6 @@
str(self.fielddescrs[i]),
str(untag(self.fieldnums[i])))
- def generalization_of(self, other):
- if not self._generalization_of(other):
- return False
- assert len(self.fielddescrs) == len(self.fieldstate)
- assert len(other.fielddescrs) == len(other.fieldstate)
- if len(self.fielddescrs) != len(other.fielddescrs):
- return False
-
- for i in range(len(self.fielddescrs)):
- if other.fielddescrs[i] is not self.fielddescrs[i]:
- return False
- if not self.fieldstate[i].generalization_of(other.fieldstate[i]):
- return False
-
- return True
-
- def _generalization_of(self, other):
- raise NotImplementedError
-
- def enum_forced_boxes(self, boxes, already_seen, value):
- #FIXME: assert isinstance(value, AbstractVirtualStructValue)
- key = value.get_key_box()
- if key in already_seen:
- return
- already_seen[key] = None
- if value.box is None:
- for i in range(len(self.fielddescrs)):
- v = value._fields[self.fielddescrs[i]]
- self.fieldstate[i].enum_forced_boxes(boxes, already_seen, v)
- else:
- boxes.append(value.box)
-
-
class VirtualInfo(AbstractVirtualStructInfo):
def __init__(self, known_class, fielddescrs):
AbstractVirtualStructInfo.__init__(self, fielddescrs)
@@ -516,13 +469,6 @@
debug_print("\tvirtualinfo", self.known_class.repr_rpython())
AbstractVirtualStructInfo.debug_prints(self)
- def _generalization_of(self, other):
- if not isinstance(other, VirtualInfo):
- return False
- if not self.known_class.same_constant(other.known_class):
- return False
- return True
-
class VStructInfo(AbstractVirtualStructInfo):
def __init__(self, typedescr, fielddescrs):
@@ -539,14 +485,6 @@
debug_print("\tvstructinfo", self.typedescr.repr_rpython())
AbstractVirtualStructInfo.debug_prints(self)
- def _generalization_of(self, other):
- if not isinstance(other, VStructInfo):
- return False
- if self.typedescr is not other.typedescr:
- return False
- return True
-
-
class VArrayInfo(AbstractVirtualInfo):
def __init__(self, arraydescr):
self.arraydescr = arraydescr
@@ -578,32 +516,6 @@
for i in self.fieldnums:
debug_print("\t\t", str(untag(i)))
- def generalization_of(self, other):
- if self.arraydescr is not other.arraydescr:
- return False
- if len(self.fieldstate) != len(other.fieldstate):
- return False
- for i in range(len(self.fieldstate)):
- if not self.fieldstate[i].generalization_of(other.fieldstate[i]):
- return False
- return True
-
- def enum_forced_boxes(self, boxes, already_seen, value):
- # FIXME: assert isinstance(value, VArrayValue)
- key = value.get_key_box()
- if key in already_seen:
- return
- already_seen[key] = None
- if value.box is None:
- for i in range(len(self.fieldstate)):
- v = value._items[i]
- self.fieldstate[i].enum_forced_boxes(boxes, already_seen, v)
- else:
- boxes.append(value.box)
-
-
-
-
class VStrPlainInfo(AbstractVirtualInfo):
"""Stands for the string made out of the characters of all fieldnums."""
diff --git a/pypy/jit/metainterp/optimizeopt/virtualstate.py b/pypy/jit/metainterp/optimizeopt/virtualstate.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/metainterp/optimizeopt/virtualstate.py
@@ -0,0 +1,245 @@
+from pypy.jit.metainterp import resume
+from pypy.jit.metainterp.optimizeopt import virtualize
+from pypy.jit.metainterp.optimizeopt.optimizer import LEVEL_CONSTANT, \
+ LEVEL_KNOWNCLASS, \
+ MININT, MAXINT
+from pypy.jit.metainterp.optimizeutil import InvalidLoop
+from pypy.jit.metainterp.optimizeopt.intutils import IntBound
+from pypy.jit.metainterp.resoperation import rop, ResOperation
+
+class AbstractVirtualStateInfo(object):
+ def generalization_of(self, other):
+ raise NotImplementedError
+
+ def generate_guards(self, other, box, cpu, extra_guards):
+ if self.generalization_of(other):
+ return
+ self._generate_guards(other, box, cpu, extra_guards)
+
+ def _generate_guards(self, other, box, cpu, extra_guards):
+ raise InvalidLoop
+
+ def enum_forced_boxes(self, boxes, already_seen, value):
+ raise NotImplementedError
+
+class AbstractVirtualStructStateInfo(AbstractVirtualStateInfo):
+ def __init__(self, fielddescrs):
+ self.fielddescrs = fielddescrs
+
+ def generalization_of(self, other):
+ if not self._generalization_of(other):
+ return False
+ assert len(self.fielddescrs) == len(self.fieldstate)
+ assert len(other.fielddescrs) == len(other.fieldstate)
+ if len(self.fielddescrs) != len(other.fielddescrs):
+ return False
+
+ for i in range(len(self.fielddescrs)):
+ if other.fielddescrs[i] is not self.fielddescrs[i]:
+ return False
+ if not self.fieldstate[i].generalization_of(other.fieldstate[i]):
+ return False
+
+ return True
+
+ def _generalization_of(self, other):
+ raise NotImplementedError
+
+ def enum_forced_boxes(self, boxes, already_seen, value):
+ assert isinstance(value, virtualize.AbstractVirtualStructValue)
+ key = value.get_key_box()
+ if key in already_seen:
+ return
+ already_seen[key] = None
+ if value.box is None:
+ for i in range(len(self.fielddescrs)):
+ v = value._fields[self.fielddescrs[i]]
+ self.fieldstate[i].enum_forced_boxes(boxes, already_seen, v)
+ else:
+ boxes.append(value.box)
+
+class VirtualStateInfo(AbstractVirtualStructStateInfo):
+ def __init__(self, known_class, fielddescrs):
+ AbstractVirtualStructStateInfo.__init__(self, fielddescrs)
+ self.known_class = known_class
+
+ def _generalization_of(self, other):
+ if not isinstance(other, VirtualStateInfo):
+ return False
+ if not self.known_class.same_constant(other.known_class):
+ return False
+ return True
+
+class VStructStateInfo(AbstractVirtualStructStateInfo):
+ def __init__(self, typedescr, fielddescrs):
+ AbstractVirtualStructStateInfo.__init__(self, fielddescrs)
+ self.typedescr = typedescr
+
+ def _generalization_of(self, other):
+ if not isinstance(other, VStructStateInfo):
+ return False
+ if self.typedescr is not other.typedescr:
+ return False
+ return True
+
+class VArrayStateInfo(AbstractVirtualStateInfo):
+ def __init__(self, arraydescr):
+ self.arraydescr = arraydescr
+
+ def generalization_of(self, other):
+ if self.arraydescr is not other.arraydescr:
+ return False
+ if len(self.fieldstate) != len(other.fieldstate):
+ return False
+ for i in range(len(self.fieldstate)):
+ if not self.fieldstate[i].generalization_of(other.fieldstate[i]):
+ return False
+ return True
+
+ def enum_forced_boxes(self, boxes, already_seen, value):
+ assert isinstance(value, virtualize.VArrayValue)
+ key = value.get_key_box()
+ if key in already_seen:
+ return
+ already_seen[key] = None
+ if value.box is None:
+ for i in range(len(self.fieldstate)):
+ v = value._items[i]
+ self.fieldstate[i].enum_forced_boxes(boxes, already_seen, v)
+ else:
+ boxes.append(value.box)
+
+class NotVirtualStateInfo(AbstractVirtualStateInfo):
+ def __init__(self, value):
+ self.known_class = value.known_class
+ self.level = value.level
+ if value.intbound is None:
+ self.intbound = IntBound(MININT, MAXINT)
+ else:
+ self.intbound = value.intbound.clone()
+ if value.is_constant():
+ self.constbox = value.box
+ else:
+ self.constbox = None
+
+ def generalization_of(self, other):
+ # XXX This will always retrace instead of forcing anything which
+ # might be what we want sometimes?
+ if not isinstance(other, NotVirtualStateInfo):
+ return False
+ if other.level < self.level:
+ return False
+ if self.level == LEVEL_CONSTANT:
+ if not self.constbox.same_constant(other.constbox):
+ return False
+ elif self.level == LEVEL_KNOWNCLASS:
+ if self.known_class != other.known_class: # FIXME: use issubclass?
+ return False
+ return self.intbound.contains_bound(other.intbound)
+
+ def _generate_guards(self, other, box, cpu, extra_guards):
+ if not isinstance(other, NotVirtualStateInfo):
+ raise InvalidLoop
+ if self.level == LEVEL_KNOWNCLASS and \
+ box.nonnull() and \
+ self.known_class.same_constant(cpu.ts.cls_of_box(box)):
+ # Note: This is only a hint on what the class of box was
+ # during the trace. There are actually no guarentees that this
+ # box realy comes from a trace. The hint is used here to choose
+ # between either eimtting a guard_class and jumping to an
+ # excisting compiled loop or retracing the loop. Both
+ # alternatives will always generate correct behaviour, but
+ # performace will differ.
+ op = ResOperation(rop.GUARD_CLASS, [box, self.known_class], None)
+ extra_guards.append(op)
+ return
+ # Remaining cases are probably not interesting
+ raise InvalidLoop
+ if self.level == LEVEL_CONSTANT:
+ import pdb; pdb.set_trace()
+ raise NotImplementedError
+
+ def enum_forced_boxes(self, boxes, already_seen, value):
+ if self.level == LEVEL_CONSTANT:
+ return
+ key = value.get_key_box()
+ if key not in already_seen:
+ boxes.append(value.force_box())
+ already_seen[value.get_key_box()] = None
+
+
+class VirtualState(object):
+ def __init__(self, state):
+ self.state = state
+
+ def generalization_of(self, other):
+ assert len(self.state) == len(other.state)
+ for i in range(len(self.state)):
+ if not self.state[i].generalization_of(other.state[i]):
+ return False
+ return True
+
+ def generate_guards(self, other, args, cpu, extra_guards):
+ assert len(self.state) == len(other.state) == len(args)
+ for i in range(len(self.state)):
+ self.state[i].generate_guards(other.state[i], args[i],
+ cpu, extra_guards)
+
+ def make_inputargs(self, values):
+ assert len(values) == len(self.state)
+ inputargs = []
+ seen_inputargs = {}
+ for i in range(len(values)):
+ self.state[i].enum_forced_boxes(inputargs, seen_inputargs,
+ values[i])
+ return inputargs
+
+
+class VirtualStateAdder(resume.ResumeDataVirtualAdder):
+ def __init__(self, optimizer):
+ self.fieldboxes = {}
+ self.optimizer = optimizer
+ self.info = {}
+
+ def register_virtual_fields(self, keybox, fieldboxes):
+ self.fieldboxes[keybox] = fieldboxes
+
+ def already_seen_virtual(self, keybox):
+ return keybox in self.fieldboxes
+
+ def getvalue(self, box):
+ return self.optimizer.getvalue(box)
+
+ def state(self, box):
+ value = self.getvalue(box)
+ box = value.get_key_box()
+ try:
+ info = self.info[box]
+ except KeyError:
+ if value.is_virtual():
+ self.info[box] = info = value.make_virtual_info(self, None)
+ flds = self.fieldboxes[box]
+ info.fieldstate = [self.state(b) for b in flds]
+ else:
+ self.info[box] = info = self.make_not_virtual(value)
+ return info
+
+ def get_virtual_state(self, jump_args):
+ for box in jump_args:
+ value = self.getvalue(box)
+ value.get_args_for_fail(self)
+ return VirtualState([self.state(box) for box in jump_args])
+
+
+ def make_not_virtual(self, value):
+ return NotVirtualStateInfo(value)
+
+ def make_virtual(self, known_class, fielddescrs):
+ return VirtualStateInfo(known_class, fielddescrs)
+
+ def make_vstruct(self, typedescr, fielddescrs):
+ return VStructStateInfo(typedescr, fielddescrs)
+
+ def make_varray(self, arraydescr):
+ return VArrayStateInfo(arraydescr)
+
More information about the Pypy-commit
mailing list