Author: Richard Plangger <[email protected]>
Branch: vecopt2
Changeset: r77094:e515a3389dbb
Date: 2015-03-26 17:24 +0100
http://bitbucket.org/pypy/pypy/changeset/e515a3389dbb/
Log: dependency graph now tracks array modifications and discards edges
of proven cell access to not overlap
diff --git a/rpython/jit/metainterp/optimizeopt/dependency.py
b/rpython/jit/metainterp/optimizeopt/dependency.py
--- a/rpython/jit/metainterp/optimizeopt/dependency.py
+++ b/rpython/jit/metainterp/optimizeopt/dependency.py
@@ -1,4 +1,5 @@
-from rpython.jit.metainterp.optimizeopt.util import MemoryRef
+import py
+from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method
from rpython.jit.metainterp.resoperation import rop
from rpython.jit.codewriter.effectinfo import EffectInfo
from rpython.jit.metainterp.history import BoxPtr, ConstPtr, ConstInt, BoxInt
@@ -52,13 +53,12 @@
self.defs = {}
def define(self, arg, index, argcell=None):
- print "def", arg, "at", index, "cell", argcell
if arg in self.defs:
self.defs[arg].append((index,argcell))
else:
self.defs[arg] = [(index,argcell)]
- def definition_index(self, arg, index, argcell=None):
+ def definition_index(self, arg, index = -1, argcell=None):
def_chain = self.defs[arg]
if len(def_chain) == 1:
return def_chain[0][0]
@@ -66,13 +66,16 @@
if argcell == None:
return def_chain[-1][0]
else:
+ assert index != -1
i = len(def_chain)-1
try:
mref = self.memory_refs[index]
while i >= 0:
def_index = def_chain[i][0]
- oref = self.memory_refs[def_index]
- if mref.indices_can_alias(oref):
+ oref = self.memory_refs.get(def_index)
+ if oref is not None and mref.indices_can_alias(oref):
+ return def_index
+ elif oref is None:
return def_index
i -= 1
except KeyError:
@@ -102,8 +105,8 @@
self.operations = operations
self.memory_refs = memory_refs
self.adjacent_list = [ [] for i in range(len(self.operations)) ]
+ self.integral_mod = IntegralMod()
self.build_dependencies(self.operations)
- self.integral_mod = IntegralMod()
def build_dependencies(self, operations):
""" This is basically building the definition-use chain and saving this
@@ -134,7 +137,6 @@
for arg in op.getarglist():
self._def_use(arg, i, tracker)
else:
- self.update_memory_ref(op, i, integral_mod)
self.put_edges_for_complex_objects(op, i, tracker)
# guard specifics
@@ -144,27 +146,32 @@
if i > 0:
self._guard_dependency(op, i, operations, tracker)
- def update_memory_ref(self, op, index):
+ def update_memory_ref(self, op, index, tracker):
if index not in self.memory_refs:
return
memref = self.memory_refs[index]
self.integral_mod.reset()
+ try:
+ curidx = tracker.definition_index(memref.origin)
+ except KeyError:
+ return
+ curop = self.operations[curidx]
while True:
- for dep in self.get_defs(index):
- op = operations[dep.idx_from]
- if op.result == memref.origin:
- index = dep.idx_from
- break
- else:
- break # cannot go further, this might be the label, or a
constant
- self.integral_mod.inspect_operation(op)
+ self.integral_mod.inspect_operation(curop)
if self.integral_mod.is_const_mod:
self.integral_mod.update_memory_ref(memref)
else:
break # an operation that is not tractable
+ for dep in self.get_defs(curidx):
+ curop = self.operations[dep.idx_from]
+ if curop.result == memref.origin:
+ curidx = dep.idx_from
+ break
+ else:
+ break # cannot go further, this might be the label, or a
constant
def put_edges_for_complex_objects(self, op, index, tracker):
- self.update_memory_ref(op, index)
+ self.update_memory_ref(op, index, tracker)
if self.loads_from_complex_object(op):
# If this complex object load operation loads an index that has
been
# modified, the last modification should be used to put a def-use
edge.
@@ -189,7 +196,7 @@
try:
# A trace is not in SSA form, but this complex
object
# modification introduces a WAR/WAW dependency
- def_idx = tracker.definition_index(arg, index)
+ def_idx = tracker.definition_index(arg)
for dep in self.get_uses(def_idx):
if dep.idx_to >= index:
break
@@ -368,11 +375,6 @@
opnum = op.getopnum()
return rop.SETARRAYITEM_GC<= opnum and opnum <= rop.UNICODESETITEM
-
-# Utilities for array references.
-# Needed by dependency.py and vectorize.py
-# ____________________________________________________________
-
class IntegralMod(object):
""" Calculates integral modifications on an integer object.
The operations must be provided in backwards direction and of one
@@ -380,8 +382,7 @@
See MemoryRef for an example.
"""
- def __init__(self, optimizer):
- self.optimizer = optimizer
+ def __init__(self):
self.reset()
def reset(self):
@@ -403,17 +404,15 @@
def operation_{name}(self, op):
box_a0 = op.getarg(0)
box_a1 = op.getarg(1)
- a0 = self.optimizer.getvalue(box_a0)
- a1 = self.optimizer.getvalue(box_a1)
self.is_const_mod = True
- if self.is_const_integral(a0) and self.is_const_integral(a1):
+ if self.is_const_integral(box_a0) and self.is_const_integral(box_a1):
self.used_box = None
self.constant += self._update_additive(box_a0.getint() {op} \
box_a1.getint())
- elif self.is_const_integral(a0):
+ elif self.is_const_integral(box_a0):
self.constant {op}= self._update_additive(box_a0.getint())
self.used_box = box_a1
- elif self.is_const_integral(a1):
+ elif self.is_const_integral(box_a1):
self.constant {op}= self._update_additive(box_a1.getint())
self.used_box = box_a0
else:
@@ -429,19 +428,17 @@
def operation_{name}(self, op):
box_a0 = op.getarg(0)
box_a1 = op.getarg(1)
- a0 = self.optimizer.getvalue(box_a0)
- a1 = self.optimizer.getvalue(box_a1)
self.is_const_mod = True
- if self.is_const_integral(a0) and self.is_const_integral(a1):
+ if self.is_const_integral(box_a0) and self.is_const_integral(box_a1):
# here this factor becomes a constant, thus it is
# handled like any other additive operation
self.used_box = None
self.constant += self._update_additive(box_a0.getint() {cop} \
box_a1.getint())
- elif a0.is_constant():
+ elif self.is_const_integral(box_a0):
self.coefficient_{tgt} {op}= box_a0.getint()
self.used_box = box_a1
- elif self.is_const_integral(a1):
+ elif self.is_const_integral(box_a1):
self.coefficient_{tgt} {op}= box_a1.getint()
self.used_box = box_a0
else:
@@ -511,7 +508,7 @@
"""
match, off = self.calc_difference(other)
if match:
- return off != 0
+ return off == 0
return False
def __eq__(self, other):
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_dependency.py
b/rpython/jit/metainterp/optimizeopt/test/test_dependency.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_dependency.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_dependency.py
@@ -4,19 +4,21 @@
LLtypeMixin, BaseTest, FakeMetaInterpStaticData,
convert_old_style_to_targets)
from rpython.jit.metainterp.history import TargetToken, JitCellToken, TreeLoop
from rpython.jit.metainterp.optimizeopt.dependency import (DependencyGraph,
Dependency,
- IntegralMod)
+ IntegralMod, MemoryRef)
+from rpython.jit.metainterp.optimizeopt.vectorize import LoopVectorizeInfo
from rpython.jit.metainterp.resoperation import rop, ResOperation
class DepTestHelper(BaseTest):
- def build_dependency(self, ops, memory_refs = False):
+ def build_dependency(self, ops, refs = False):
loop = self.parse_loop(ops)
- refs = {}
- if memory_refs:
- opt = Optimizer(None, None, loop)
-
-
- self.last_graph = DependencyGraph(loop.operations, refs)
+ lvi = LoopVectorizeInfo()
+ if refs:
+ lvi.track_memory_refs = True
+ for i,op in enumerate(loop.operations):
+ lvi.index = i
+ lvi.inspect_operation(op)
+ self.last_graph = DependencyGraph(loop.operations, lvi.memory_refs)
for i in range(len(self.last_graph.adjacent_list)):
self.assert_independent(i,i)
return self.last_graph
@@ -298,12 +300,12 @@
setarrayitem_raw(p0, i2, 2, descr=floatarraydescr) #2
jump(p0, i1)
"""
+ dep_graph = self.build_dependency(ops, True)
+ self.assert_edges(dep_graph,
+ [ [1,2,3,4], [0], [0,3], [0,2,4], [0,3] ])
dep_graph = self.build_dependency(ops)
self.assert_edges(dep_graph,
- [ [1,2,4], [0,3], [0,3], [0,1,2,4], [0,3] ])
- dep_graph = self.build_dependency(ops, memory_refs=True)
- self.assert_edges(dep_graph,
- [ [1,2,3,4], [0], [0,3], [0,2,4], [0,3] ])
+ [ [1,2,4], [0,3], [0,3], [1,2,4], [0,3] ])
class TestLLtype(BaseTestDependencyGraph, LLtypeMixin):
pass
diff --git a/rpython/jit/metainterp/optimizeopt/vectorize.py
b/rpython/jit/metainterp/optimizeopt/vectorize.py
--- a/rpython/jit/metainterp/optimizeopt/vectorize.py
+++ b/rpython/jit/metainterp/optimizeopt/vectorize.py
@@ -2,9 +2,9 @@
import py
from rpython.rtyper.lltypesystem import lltype, rffi
from rpython.jit.metainterp.optimizeopt.optimizer import Optimizer,
Optimization
-from rpython.jit.metainterp.optimizeopt.util import (make_dispatcher_method,
+from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method
+from rpython.jit.metainterp.optimizeopt.dependency import (DependencyGraph,
MemoryRef, IntegralMod)
-from rpython.jit.metainterp.optimizeopt.dependency import DependencyGraph
from rpython.jit.metainterp.resoperation import rop
from rpython.jit.metainterp.resume import Snapshot
from rpython.rlib.debug import debug_print, debug_start, debug_stop
@@ -31,7 +31,7 @@
def __init__(self, metainterp_sd, jitdriver_sd, loop, optimizations):
Optimizer.__init__(self, metainterp_sd, jitdriver_sd, loop,
optimizations)
- self.vec_info = LoopVectorizeInfo(self)
+ self.vec_info = LoopVectorizeInfo()
self.memory_refs = []
self.dependency_graph = None
self.first_debug_merge_point = False
@@ -71,6 +71,7 @@
op = loop.operations[i].clone()
operations.append(op)
self.emit_unrolled_operation(op)
+ self.vec_info.index = len(self._newoperations)-1
self.vec_info.inspect_operation(op)
orig_jump_args = jump_op.getarglist()[:]
@@ -112,6 +113,7 @@
copied_op.result = new_assigned_box
#
self.emit_unrolled_operation(copied_op)
+ self.vec_info.index = len(self._newoperations)-1
self.vec_info.inspect_operation(copied_op)
# the jump arguments have been changed
@@ -343,22 +345,19 @@
return self.opidx == other.opidx and self.memref == other.memref
return False
-
-
class LoopVectorizeInfo(object):
- def __init__(self, optimizer):
- self.optimizer = optimizer
+ def __init__(self):
self.smallest_type_bytes = 0
self.memory_refs = {}
self.track_memory_refs = False
+ self.index = 0
array_access_source = """
def operation_{name}(self, op):
descr = op.getdescr()
if self.track_memory_refs:
- idx = len(self.optimizer._newoperations)-1
- self.memory_refs[idx] = \
+ self.memory_refs[self.index] = \
MemoryRef(op.getarg(0), op.getarg(1), op.getdescr())
if not descr.is_array_of_pointers():
byte_count = descr.get_item_size_in_bytes()
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit