[pypy-commit] pypy optresult-unroll: a completely different approach
fijal
noreply at buildbot.pypy.org
Mon Jul 6 14:57:19 CEST 2015
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: optresult-unroll
Changeset: r78456:cbf2d99e2ae8
Date: 2015-07-06 14:57 +0200
http://bitbucket.org/pypy/pypy/changeset/cbf2d99e2ae8/
Log: a completely different approach
diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py
--- a/rpython/jit/metainterp/compile.py
+++ b/rpython/jit/metainterp/compile.py
@@ -24,6 +24,37 @@
raise SwitchToBlackhole(Counters.ABORT_BRIDGE)
+class LoopCompileData(object):
+ """ An object that accumulates all of the necessary info for
+ the optimization phase, but does not actually have any other state
+
+ This is the case of label() ops label()
+ """
+ def __init__(self, start_label, end_label, operations):
+ self.start_label = start_label
+ self.end_label = end_label
+ assert start_label.getopnum() == rop.LABEL
+ assert end_label.getopnum() == rop.LABEL
+ self.operations = operations
+
+ def forget_optimization_info(self):
+ for arg in self.start_label.getarglist():
+ arg.set_forwarded(None)
+ for op in self.operations:
+ op.set_forwarded(None)
+
+ def optimize(self, metainterp_sd, jitdriver_sd, optimizations, unroll):
+ from rpython.jit.metainterp.optimizeopt.unroll import UnrollOptimizer
+
+ if unroll:
+ opt = UnrollOptimizer(metainterp_sd, jitdriver_sd, optimizations)
+ return opt.optimize_preamble(self.start_label, self.end_label,
+ self.operations)
+ xxx
+ else:
+ xxx
+
+
def show_procedures(metainterp_sd, procedure=None, error=None):
# debugging
if option and (option.view or option.viewloops):
@@ -104,10 +135,8 @@
# ____________________________________________________________
-def compile_loop(metainterp, greenkey, start,
- inputargs, jumpargs,
- full_preamble_needed=True,
- try_disabling_unroll=False):
+def compile_loop(metainterp, greenkey, start, inputargs, jumpargs,
+ full_preamble_needed=True, try_disabling_unroll=False):
"""Try to compile a new procedure by closing the current history back
to the first operation.
"""
diff --git a/rpython/jit/metainterp/optimizeopt/__init__.py b/rpython/jit/metainterp/optimizeopt/__init__.py
--- a/rpython/jit/metainterp/optimizeopt/__init__.py
+++ b/rpython/jit/metainterp/optimizeopt/__init__.py
@@ -4,7 +4,6 @@
from rpython.jit.metainterp.optimizeopt.virtualize import OptVirtualize
from rpython.jit.metainterp.optimizeopt.heap import OptHeap
from rpython.jit.metainterp.optimizeopt.vstring import OptString
-from rpython.jit.metainterp.optimizeopt.unroll import optimize_unroll
from rpython.jit.metainterp.optimizeopt.simplify import OptSimplify
from rpython.jit.metainterp.optimizeopt.pure import OptPure
from rpython.jit.metainterp.optimizeopt.earlyforce import OptEarlyForce
@@ -47,26 +46,17 @@
return optimizations, unroll
-def optimize_trace(metainterp_sd, jitdriver_sd, loop, enable_opts,
- inline_short_preamble=True, start_state=None,
- export_state=True):
+def optimize_trace(metainterp_sd, jitdriver_sd, compile_data):
"""Optimize loop.operations to remove internal overheadish operations.
"""
-
debug_start("jit-optimize")
+ #inputargs = start_label.getarglist()
try:
- loop.logops = metainterp_sd.logger_noopt.log_loop(loop.inputargs,
- loop.operations)
- optimizations, unroll = build_opt_chain(metainterp_sd, enable_opts)
- if unroll:
- return optimize_unroll(metainterp_sd, jitdriver_sd, loop,
- optimizations,
- inline_short_preamble, start_state,
- export_state)
- else:
- optimizer = Optimizer(metainterp_sd, jitdriver_sd, loop,
- optimizations)
- optimizer.propagate_all_forward()
+ #logops = metainterp_sd.logger_noopt.log_loop(inputargs, operations)
+ optimizations, unroll = build_opt_chain(metainterp_sd,
+ compile_data.enable_opts)
+ return compile_data.optimize(metainterp_sd, jitdriver_sd,
+ optimizations, unroll)
finally:
debug_stop("jit-optimize")
diff --git a/rpython/jit/metainterp/optimizeopt/optimizer.py b/rpython/jit/metainterp/optimizeopt/optimizer.py
--- a/rpython/jit/metainterp/optimizeopt/optimizer.py
+++ b/rpython/jit/metainterp/optimizeopt/optimizer.py
@@ -211,14 +211,10 @@
class Optimizer(Optimization):
- exporting_state = False
- emitting_dissabled = False
-
- def __init__(self, metainterp_sd, jitdriver_sd, loop, optimizations=None):
+ def __init__(self, metainterp_sd, jitdriver_sd, optimizations=None):
self.metainterp_sd = metainterp_sd
self.jitdriver_sd = jitdriver_sd
self.cpu = metainterp_sd.cpu
- self.loop = loop
self.logops = LogOperations(metainterp_sd, False)
self.interned_refs = self.cpu.ts.new_ref_dict()
self.interned_ints = {}
@@ -234,14 +230,15 @@
self.optheap = None
self.optearlyforce = None
self.optunroll = None
- # the following two fields is the data kept for unrolling,
- # those are the operations that can go to the short_preamble
- if loop is not None:
- self.call_pure_results = loop.call_pure_results
self.set_optimizations(optimizations)
self.setup()
+ def init_inparg_dict_from(self, lst):
+ self.inparg_dict = {}
+ for box in lst:
+ self.inparg_dict[box] = None
+
def set_optimizations(self, optimizations):
if optimizations:
self.first_optimization = optimizations[0]
@@ -442,18 +439,13 @@
else:
return CONST_0
- def propagate_all_forward(self, clear=True, create_inp_args=True):
- if clear:
- self.clear_newoperations()
- if create_inp_args:
- self.inparg_dict = {}
- for op in self.loop.inputargs:
- self.inparg_dict[op] = None
- for op in self.loop.operations:
+ def propagate_all_forward(self, inputargs, ops, create_inp_args=True):
+ self.init_inparg_dict_from(inputargs)
+ for op in ops:
self._really_emitted_operation = None
self.first_optimization.propagate_forward(op)
- self.loop.operations = self.get_newoperations()
- self.loop.quasi_immutable_deps = self.quasi_immutable_deps
+ #self.loop.operations = self.get_newoperations()
+ #self.loop.quasi_immutable_deps = self.quasi_immutable_deps
# accumulate counters
self.resumedata_memo.update_counters(self.metainterp_sd.profiler)
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_unroll.py b/rpython/jit/metainterp/optimizeopt/test/test_unroll.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_unroll.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_unroll.py
@@ -3,10 +3,11 @@
"""
from rpython.jit.metainterp.optimizeopt.test.test_util import BaseTest,\
- LLtypeMixin, FakeMetaInterpStaticData
-from rpython.jit.metainterp.history import (TreeLoop, AbstractDescr, ConstInt,
+ LLtypeMixin
+from rpython.jit.metainterp.history import (TreeLoop, ConstInt,
JitCellToken, TargetToken)
from rpython.jit.metainterp.resoperation import rop, ResOperation
+from rpython.jit.metainterp.compile import LoopCompileData
from rpython.jit.metainterp.optimizeopt.virtualstate import \
NotVirtualStateInfo, LEVEL_CONSTANT, LEVEL_UNKNOWN
@@ -18,7 +19,6 @@
def optimize(self, ops):
loop = self.parse(ops, postprocess=self.postprocess)
- metainterp_sd = FakeMetaInterpStaticData(self.cpu)
self.add_guard_future_condition(loop)
operations = loop.operations
jumpop = operations[-1]
@@ -34,11 +34,10 @@
token = JitCellToken()
start_label = ResOperation(rop.LABEL, inputargs, descr=TargetToken(token))
stop_label = ResOperation(rop.LABEL, jump_args, descr=token)
- preamble.operations = [start_label] + operations + [stop_label]
- start_state = self._do_optimize_loop(preamble, None,
- export_state=True)
- vs = preamble.operations[-1].getdescr().virtual_state
- return start_state, vs, loop, preamble
+ compile_data = LoopCompileData(start_label, stop_label, operations)
+ start_state, newops = self._do_optimize_loop(compile_data)
+ preamble.operations = newops
+ return start_state, loop, preamble
class TestUnroll(BaseTestUnroll):
def test_simple(self):
@@ -48,7 +47,8 @@
guard_value(i1, 1) []
jump(i1)
"""
- es, vs, loop, preamble = self.optimize(loop)
+ es, loop, preamble = self.optimize(loop)
+ vs = es.virtual_state
assert isinstance(vs.state[0], NotVirtualStateInfo)
# the virtual state is constant, so we don't need to have it in
# inputargs
@@ -65,8 +65,9 @@
i1 = int_add(i0, 1)
jump(i0)
"""
- es, vs, loop, preamble = self.optimize(loop)
+ es, loop, preamble = self.optimize(loop)
+ vs = es.virtual_state
assert isinstance(vs.state[0], NotVirtualStateInfo)
assert vs.state[0].level == LEVEL_UNKNOWN
- op = preamble.operations[1]
+ op = preamble.operations[0]
assert es.short_boxes == {op: op}
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_util.py b/rpython/jit/metainterp/optimizeopt/test/test_util.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_util.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_util.py
@@ -405,15 +405,11 @@
assert equaloplists(optimized.operations,
expected.operations, False, remap, text_right)
- def _do_optimize_loop(self, loop, call_pure_results, start_state=None,
- export_state=False):
+ def _do_optimize_loop(self, compile_data, call_pure_results=None):
from rpython.jit.metainterp.optimizeopt import optimize_trace
from rpython.jit.metainterp.optimizeopt.util import args_dict
- self.loop = loop
- operations = loop.operations
- inputargs = loop.inputargs
- loop.call_pure_results = args_dict()
+ # XXX
if call_pure_results is not None:
for k, v in call_pure_results.items():
loop.call_pure_results[list(k)] = v
@@ -423,17 +419,14 @@
if hasattr(self, 'callinfocollection'):
metainterp_sd.callinfocollection = self.callinfocollection
#
- state = optimize_trace(metainterp_sd, None, loop,
- self.enable_opts,
- start_state=start_state,
- export_state=export_state)
- compile.forget_optimization_info(operations)
- compile.forget_optimization_info(inputargs)
+ compile_data.enable_opts = self.enable_opts
+ state = optimize_trace(metainterp_sd, None, compile_data)
+ compile_data.forget_optimization_info()
return state
def unroll_and_optimize(self, loop, call_pure_results=None):
+ xxx
metainterp_sd = FakeMetaInterpStaticData(self.cpu)
- logops = LogOperations(metainterp_sd, False)
self.add_guard_future_condition(loop)
operations = loop.operations
jumpop = operations[-1]
diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py b/rpython/jit/metainterp/optimizeopt/unroll.py
--- a/rpython/jit/metainterp/optimizeopt/unroll.py
+++ b/rpython/jit/metainterp/optimizeopt/unroll.py
@@ -13,15 +13,6 @@
from rpython.rlib.debug import debug_print, debug_start, debug_stop
-# FIXME: Introduce some VirtualOptimizer super class instead
-
-def optimize_unroll(metainterp_sd, jitdriver_sd, loop, optimizations,
- inline_short_preamble=True, start_state=None,
- export_state=True):
- opt = UnrollOptimizer(metainterp_sd, jitdriver_sd, loop, optimizations)
- opt.inline_short_preamble = inline_short_preamble
- return opt.propagate_all_forward(start_state, export_state)
-
class PreambleOp(AbstractResOp):
def __init__(self, op, info):
@@ -36,18 +27,6 @@
class UnrollableOptimizer(Optimizer):
- def setup(self):
- self.importable_values = {}
- self.emitting_dissabled = False
- self.emitted_guards = 0
-
- def emit_operation(self, op):
- if self.emitting_dissabled:
- return
- if op.is_guard():
- self.emitted_guards += 1 # FIXME: can we use counter in self._emit_operation?
- self._emit_operation(op)
-
def force_op_from_preamble(self, preamble_op):
op = preamble_op.op
self.optunroll.short.append(op)
@@ -63,52 +42,27 @@
inline_short_preamble = True
- def __init__(self, metainterp_sd, jitdriver_sd, loop, optimizations):
+ def __init__(self, metainterp_sd, jitdriver_sd, optimizations):
self.optimizer = UnrollableOptimizer(metainterp_sd, jitdriver_sd,
- loop, optimizations)
+ optimizations)
self.optimizer.optunroll = self
- self.boxes_created_this_iteration = None
def get_virtual_state(self, args):
modifier = VirtualStateConstructor(self.optimizer)
return modifier.get_virtual_state(args)
- def propagate_all_forward(self, starting_state, export_state=True):
- self.optimizer.exporting_state = export_state
- loop = self.optimizer.loop
- self.optimizer.clear_newoperations()
- for op in loop.operations:
- assert op.get_forwarded() is None
- for op in loop.inputargs:
- assert op.get_forwarded() is None
-
- start_label = loop.operations[0]
- if start_label.getopnum() == rop.LABEL:
- loop.operations = loop.operations[1:]
- # We need to emit the label op before import_state() as emitting it
- # will clear heap caches
- self.optimizer.send_extra_operation(start_label)
- else:
- start_label = None
-
- patchguardop = None
- if len(loop.operations) > 1:
- patchguardop = loop.operations[-2]
- if patchguardop.getopnum() != rop.GUARD_FUTURE_CONDITION:
- patchguardop = None
-
- jumpop = loop.operations[-1]
- if jumpop.getopnum() == rop.JUMP or jumpop.getopnum() == rop.LABEL:
- loop.operations = loop.operations[:-1]
- else:
- jumpop = None
-
- self.import_state(start_label, starting_state)
- self.optimizer.inparg_dict = {}
- for box in start_label.getarglist():
- self.optimizer.inparg_dict[box] = None
- self.optimizer.propagate_all_forward(clear=False, create_inp_args=False)
-
+ def _check_no_forwarding(self, lsts):
+ for lst in lsts:
+ for op in lst:
+ assert op.get_forwarded() is None
+ assert not self.optimizer._newoperations
+
+ def optimize_preamble(self, start_label, end_label, ops):
+ self._check_no_forwarding([[start_label, end_label], ops])
+ self.optimizer.propagate_all_forward(start_label.getarglist(), ops)
+ exported_state = self.export_state(start_label, end_label)
+ return exported_state, self.optimizer._newoperations
+ # WTF is the rest of this function
if not jumpop:
return
@@ -183,7 +137,7 @@
self.optimizer.send_extra_operation(stop_label)
loop.operations = self.optimizer.get_newoperations()
return None
- final_state = self.export_state(stop_label)
+ final_state = self.export_state(start_label, stop_label)
else:
final_state = None
loop.operations.append(stop_label)
@@ -200,19 +154,16 @@
return stop_target.targeting_jitcell_token is start_target.targeting_jitcell_token
- def export_state(self, targetop):
- original_jump_args = targetop.getarglist()
- label_op = self.optimizer.loop.operations[0]
- jump_args = [self.get_box_replacement(a) for a in original_jump_args]
- virtual_state = self.get_virtual_state(jump_args)
- target_token = targetop.getdescr()
- assert isinstance(target_token, TargetToken)
- target_token.virtual_state = virtual_state
+ def export_state(self, start_label, end_label):
+ original_label_args = end_label.getarglist()
+ end_args = [self.get_box_replacement(a) for a in original_label_args]
+ virtual_state = self.get_virtual_state(end_args)
sb = ShortBoxes()
- sb.create_short_boxes(self.optimizer, jump_args)
- inparg_mapping = [(label_op.getarg(i), jump_args[i])
- for i in range(len(jump_args))]
- return ExportedState(inparg_mapping, [], sb.short_boxes)
+ sb.create_short_boxes(self.optimizer, end_args)
+ inparg_mapping = [(start_label.getarg(i), end_args[i])
+ for i in range(len(end_args)) if
+ start_label.getarg(i) is not end_args[i]]
+ return ExportedState(inparg_mapping, virtual_state, [], sb.short_boxes)
inputargs = virtual_state.make_inputargs(jump_args, self.optimizer)
@@ -297,6 +248,8 @@
# think about it, it seems to be just for consts
#for source, target in exported_state.inputarg_setup_ops:
# source.set_forwarded(target)
+ for source, target in exported_state.inputarg_mapping:
+ source.set_forwarded(target)
for op, preamble_op in exported_state.short_boxes.iteritems():
if preamble_op.is_always_pure():
@@ -709,7 +662,9 @@
* short boxes - a mapping op -> preamble_op
"""
- def __init__(self, inputarg_mapping, exported_infos, short_boxes):
+ def __init__(self, inputarg_mapping, virtual_state, exported_infos,
+ short_boxes):
self.inputarg_mapping = inputarg_mapping
+ self.virtual_state = virtual_state
self.exported_infos = exported_infos
self.short_boxes = short_boxes
More information about the pypy-commit
mailing list