[pypy-commit] pypy stmgc-c7: Update "import_stmgc.py" to show which new files need to
Author: Armin Rigo Branch: stmgc-c7 Changeset: r74516:f47c518719ce Date: 2014-11-14 11:13 +0100 http://bitbucket.org/pypy/pypy/changeset/f47c518719ce/ Log:Update "import_stmgc.py" to show which new files need to be tracked and which old files need to be deleted. Remove three old files. diff --git a/rpython/translator/stm/import_stmgc.py b/rpython/translator/stm/import_stmgc.py --- a/rpython/translator/stm/import_stmgc.py +++ b/rpython/translator/stm/import_stmgc.py @@ -7,7 +7,7 @@ The working copy comes from: hg clone https://bitbucket.org/pypy/stmgc """ -import sys, py, subprocess +import sys, py, subprocess, os def mangle(lines): yield "/* Imported by rpython/translator/stm/import_stmgc.py */\n" @@ -40,6 +40,12 @@ # stmgc_dest.join('revision').write('%s\n' % rev) print rev +# +print 'The differences between which files are tracked are:' +os.system("bash -c 'diff <(cd '%s' && hg status -macn stm/ | sort)" + " <(cd '%s' && hg status -macn stm/ | sort)'" +% (stmgc_dest, stmgc_dir)) +print 'Unless none are listed, use "hg add" or "hg remove".' if __name__ == '__main__': if len(sys.argv) != 2: diff --git a/rpython/translator/stm/src_stm/stm/prof.h b/rpython/translator/stm/src_stm/stm/prof.h deleted file mode 100644 --- a/rpython/translator/stm/src_stm/stm/prof.h +++ /dev/null @@ -1,3 +0,0 @@ -/* Imported by rpython/translator/stm/import_stmgc.py */ - -static void forksupport_open_new_profiling_file(void); diff --git a/rpython/translator/stm/src_stm/stm/timing.c b/rpython/translator/stm/src_stm/stm/timing.c deleted file mode 100644 --- a/rpython/translator/stm/src_stm/stm/timing.c +++ /dev/null @@ -1,92 +0,0 @@ -/* Imported by rpython/translator/stm/import_stmgc.py */ -#ifndef _STM_CORE_H_ -# error "must be compiled via stmgc.c" -#endif - - -static inline void add_timing(stm_thread_local_t *tl, enum stm_time_e category, - double elapsed) -{ -tl->timing[category] += elapsed; -tl->events[category] += 1; -} - -#define TIMING_CHANGE(tl, newstate) \ -double curtime = get_stm_time();\ -double elasped = curtime - tl->_timing_cur_start; \ -enum stm_time_e oldstate = tl->_timing_cur_state; \ -add_timing(tl, oldstate, elasped); \ -tl->_timing_cur_state = newstate; \ -tl->_timing_cur_start = curtime - -static enum stm_time_e change_timing_state(enum stm_time_e newstate) -{ -stm_thread_local_t *tl = STM_SEGMENT->running_thread; -TIMING_CHANGE(tl, newstate); -return oldstate; -} - -static double change_timing_state_tl(stm_thread_local_t *tl, - enum stm_time_e newstate) -{ -TIMING_CHANGE(tl, newstate); -return elasped; -} - -static void timing_end_transaction(enum stm_time_e attribute_to) -{ -stm_thread_local_t *tl = STM_SEGMENT->running_thread; -TIMING_CHANGE(tl, STM_TIME_OUTSIDE_TRANSACTION); -double time_this_transaction = tl->timing[STM_TIME_RUN_CURRENT]; -add_timing(tl, attribute_to, time_this_transaction); -tl->timing[STM_TIME_RUN_CURRENT] = 0.0f; - -if (attribute_to != STM_TIME_RUN_COMMITTED) { -struct stm_priv_segment_info_s *pseg = -get_priv_segment(STM_SEGMENT->segment_num); -marker_copy(tl, pseg, attribute_to, time_this_transaction); -} -} - -static const char *timer_names[] = { -"outside transaction", -"run current", -"run committed", -"run aborted write write", -"run aborted write read", -"run aborted inevitable", -"run aborted other", -"wait free segment", -"wait write read", -"wait inevitable", -"wait other", -"sync commit soon", -"bookkeeping", -"minor gc", -"major gc", -"sync pause", -}; - -void stm_flush_timing(stm_thread_local_t *tl, int verbose) -{ -enum stm_time_e category = tl->_timing_cur_state; -uint64_t oldevents = tl->events[category]; -TIMING_CHANGE(tl, category); -tl->events[category] = oldevents; - -assert((sizeof(timer_names) / sizeof(timer_names[0])) == _STM_TIME_N); -if (verbose > 0) { -int i; -s_mutex_lock(); -fprintf(stderr, "thread %p:\n", tl); -for (i = 0; i < _STM_TIME_N; i++) { -fprintf(stderr, "%-24s %9u %8.3f s\n", -timer_names[i], tl->events[i], (double)tl->timing[i]); -} -fprintf(stderr, "%-24s %6s %11.6f s\n", -"longest recorded marker", "", tl->longest_marker_time); -fprintf(stderr, "\"%.*s\"\n", -(int)_STM_MARKER_LEN, tl->longest_marker_self); -s_mutex_unlock(); -} -} diff --git a/rpython/translator/stm/src_stm/stm/timing.h b/rpython/translator/stm/src_stm/stm/timing.h deleted file mode 100644 --- a/rpython/translator/stm/src_stm/stm/timing.h +++ /dev/null @@ -1,15 +0,0 @@ -/* Imported by rpython/trans
[pypy-commit] pypy stmgc-c7: Add the missing part about recording pauses.
Author: Armin Rigo Branch: stmgc-c7 Changeset: r74517:31351821e9e1 Date: 2014-11-14 11:32 +0100 http://bitbucket.org/pypy/pypy/changeset/31351821e9e1/ Log:Add the missing part about recording pauses. diff --git a/pypy/stm/print_stm_log.py b/pypy/stm/print_stm_log.py --- a/pypy/stm/print_stm_log.py +++ b/pypy/stm/print_stm_log.py @@ -85,16 +85,35 @@ def transaction_start(self, entry): self._start = entry self._conflict = None +self._pause = None +self._paused_time = 0.0 def transaction_stop(self, entry): transaction_time = entry.timestamp - self._start.timestamp +transaction_time -= self._paused_time +assert transaction_time >= 0.0 self.cpu_time += transaction_time self._start = None +self._pause = None if self._conflict and entry.event == STM_TRANSACTION_ABORT: c = self._conflict[1] c.aborted_time += transaction_time self._conflict = None +def transaction_pause(self, entry): +self._pause = entry + +def transaction_unpause(self, entry): +if self._pause is None: +return +pause_time = entry.timestamp - self._pause.timestamp +self._paused_time += pause_time +self._pause = None +if self._conflict and self._conflict[0] == "local": +c = self._conflict[1] +c.paused_time += pause_time +self._conflict = None + def in_transaction(self): return self._start is not None @@ -165,7 +184,14 @@ t2 = threads.get(entry.otherthreadnum) if t2 is not None and t2.in_transaction(): t2._conflict = ("remote", c, entry) -#elif entry.event == ...STM_WAIT... +elif entry.event in (STM_WAIT_SYNC_PAUSE, STM_WAIT_CONTENTION): +t = threads.get(entry.threadnum) +if t is not None and t.in_transaction(): +t.transaction_pause(entry) +elif entry.event == STM_WAIT_DONE: +t = threads.get(entry.threadnum) +if t is not None and t.in_transaction(): +t.transaction_unpause(entry) # total_cpu_time = sum([t.cpu_time for t in threads.values()]) print 'Total CPU time in STM mode: %.3fs (%s)' % ( ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy stmgc-c7: update from the changes done in the list of operations
Author: Armin Rigo Branch: stmgc-c7 Changeset: r74518:4491d856926c Date: 2014-11-14 11:46 +0100 http://bitbucket.org/pypy/pypy/changeset/4491d856926c/ Log:update from the changes done in the list of operations diff --git a/rpython/translator/stm/inevitable.py b/rpython/translator/stm/inevitable.py --- a/rpython/translator/stm/inevitable.py +++ b/rpython/translator/stm/inevitable.py @@ -31,11 +31,14 @@ GETTERS = set(['getfield', 'getarrayitem', 'getinteriorfield', 'raw_load']) SETTERS = set(['setfield', 'setarrayitem', 'setinteriorfield', 'raw_store']) MALLOCS = set(['malloc', 'malloc_varsize', - 'malloc_nonmovable', 'malloc_nonmovable_varsize', 'raw_malloc', + 'do_malloc_fixedsize', 'do_malloc_varsize', 'do_malloc_fixedsize_clear', 'do_malloc_varsize_clear']) FREES = set(['free', 'raw_free']) +for opname in ALWAYS_ALLOW_OPERATIONS | GETTERS | SETTERS | MALLOCS | FREES: +getattr(lloperation.llop, opname) # the opname must exist! + # def should_turn_inevitable_getter_setter(op): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy stmgc-c7: add useful time line to print_stm_log in order to see if the time was lost in
Author: Remi Meier Branch: stmgc-c7 Changeset: r74519:91bce27dd903 Date: 2014-11-14 13:29 +0100 http://bitbucket.org/pypy/pypy/changeset/91bce27dd903/ Log:add useful time line to print_stm_log in order to see if the time was lost in the initialization or shutdown phases instead of the actual runtime. diff --git a/pypy/stm/print_stm_log.py b/pypy/stm/print_stm_log.py --- a/pypy/stm/print_stm_log.py +++ b/pypy/stm/print_stm_log.py @@ -126,6 +126,7 @@ self.aborted_time = 0.0 self.paused_time = 0.0 self.num_events = 0 +self.timestamps = [] def sortkey(self): return self.aborted_time + self.paused_time @@ -149,7 +150,8 @@ return r + '%' def dump(logentries): -total_time = logentries[-1].timestamp - logentries[0].timestamp +start_time, stop_time = logentries[0].timestamp, logentries[-1].timestamp +total_time = stop_time - start_time print 'Total real time: %.3fs' % (total_time,) # threads = {} @@ -173,6 +175,7 @@ if c is None: c = conflicts[summary] = ConflictSummary(*summary) c.num_events += 1 +c.timestamps.append(entry.timestamp) t = threads.get(entry.threadnum) if t is not None and t.in_transaction(): t._conflict = ("local", c, entry) @@ -193,18 +196,25 @@ if t is not None and t.in_transaction(): t.transaction_unpause(entry) # -total_cpu_time = sum([t.cpu_time for t in threads.values()]) +total_cpu_time = sum([v.cpu_time for v in threads.values()]) print 'Total CPU time in STM mode: %.3fs (%s)' % ( total_cpu_time, percent(total_cpu_time, total_time)) print # values = sorted(conflicts.values(), key=ConflictSummary.sortkey) for c in values[-1:-15:-1]: +intervals = 48 +timeline = [0] * intervals +for t in c.timestamps: +idx = int((t - start_time) / total_time * intervals) +timeline[idx] += 1 + print '%.3fs lost in aborts, %.3fs paused (%dx %s)' % ( c.aborted_time, c.paused_time, c.num_events, event_name[c.event]) print_marker(c.marker1) if c.marker2: print_marker(c.marker2) +print "time line:", "".join(['x' if i else '.' for i in timeline]) print ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] buildbot default: Copy libpypy-c.so to pypy checkout for translated test build
Author: David Schneider Branch: Changeset: r922:b699815f9193 Date: 2014-11-14 14:53 +0100 http://bitbucket.org/pypy/buildbot/changeset/b699815f9193/ Log:Copy libpypy-c.so to pypy checkout for translated test build diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -564,6 +564,13 @@ command=command, haltOnFailure=True, workdir='.')) +# copy libpypy-c.so to the expected location within the pypy source checkout, if available +command = 'if [ -e pypy-c/bin/libpypy-c.so ]; then cp -v pypy-c/bin/libpypy-c.so build/pypy/goal/; fi;' +self.addStep(ShellCmd( +description="move libpypy-c.so", +command=command, +haltOnFailure=True, +workdir='.')) # copy generated and copied header files to build/include self.addStep(ShellCmd( description="move header files", ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy optresult: hack hack hack
Author: Maciej Fijalkowski Branch: optresult Changeset: r74521:38b07f93b97a Date: 2014-11-14 18:15 +0200 http://bitbucket.org/pypy/pypy/changeset/38b07f93b97a/ Log:hack hack hack diff --git a/rpython/jit/metainterp/executor.py b/rpython/jit/metainterp/executor.py --- a/rpython/jit/metainterp/executor.py +++ b/rpython/jit/metainterp/executor.py @@ -4,8 +4,10 @@ from rpython.rtyper.lltypesystem import lltype, rstr from rpython.rlib.rarithmetic import ovfcheck, r_longlong, is_valid_int from rpython.rlib.unroll import unrolling_iterable -from rpython.jit.metainterp.history import BoxInt, BoxPtr, BoxFloat, check_descr +from rpython.rlib.objectmodel import specialize +from rpython.jit.metainterp.history import check_descr from rpython.jit.metainterp.history import INT, REF, FLOAT, VOID, AbstractDescr +from rpython.jit.metainterp.history import ConstInt, ConstFloat, ConstPtr from rpython.jit.metainterp import resoperation from rpython.jit.metainterp.resoperation import rop from rpython.jit.metainterp.blackhole import BlackholeInterpreter, NULL @@ -14,6 +16,7 @@ # def do_call(cpu, metainterp, argboxes, descr): +xxx assert metainterp is not None # count the number of arguments of the different types count_i = count_r = count_f = 0 @@ -141,6 +144,7 @@ cpu.bh_setarrayitem_raw_i(array, index, itembox.getint(), arraydescr) def do_getinteriorfield_gc(cpu, _, arraybox, indexbox, descr): + array = arraybox.getref_base() index = indexbox.getint() if descr.is_pointer_field(): @@ -175,6 +179,7 @@ return cpu.bh_getfield_gc_f(struct, fielddescr) def do_getfield_raw(cpu, _, structbox, fielddescr): + check_descr(fielddescr) struct = structbox.getint() if fielddescr.is_pointer_field(): @@ -212,6 +217,7 @@ cpu.bh_raw_store_i(addr, offset, valuebox.getint(), arraydescr) def do_raw_load(cpu, _, addrbox, offsetbox, arraydescr): +xxx addr = addrbox.getint() offset = offsetbox.getint() if arraydescr.is_array_of_pointers(): @@ -228,7 +234,7 @@ return cpu.bh_new_with_vtable(vtable, descr) def do_new_with_vtable(cpu, _, clsbox): -return BoxPtr(exec_new_with_vtable(cpu, clsbox)) +return exec_new_with_vtable(cpu, clsbox) def do_int_add_ovf(cpu, metainterp, box1, box2): # the overflow operations can be called without a metainterp, if an @@ -241,7 +247,7 @@ assert metainterp is not None metainterp.execute_raised(OverflowError(), constant=True) z = 0 -return BoxInt(z) +return z def do_int_sub_ovf(cpu, metainterp, box1, box2): a = box1.getint() @@ -252,7 +258,7 @@ assert metainterp is not None metainterp.execute_raised(OverflowError(), constant=True) z = 0 -return BoxInt(z) +return z def do_int_mul_ovf(cpu, metainterp, box1, box2): a = box1.getint() @@ -263,16 +269,16 @@ assert metainterp is not None metainterp.execute_raised(OverflowError(), constant=True) z = 0 -return BoxInt(z) +return z def do_same_as_i(cpu, _, v): -return v +return v.getint() def do_same_as_r(cpu, _, v): -return v +return v.getref_base() def do_same_as_f(cpu, _, v): -return v +return v.getfloatstorage() def do_copystrcontent(cpu, _, srcbox, dstbox, srcstartbox, dststartbox, lengthbox): @@ -339,7 +345,7 @@ # parameters. name = 'bhimpl_' + key.lower() if hasattr(BlackholeInterpreter, name): -func = make_execute_function_with_boxes( +func = make_execute_function( key.lower(), getattr(BlackholeInterpreter, name).im_func) if func is not None: @@ -374,7 +380,7 @@ raise AssertionError("missing %r" % (key,)) return execute_by_num_args -def make_execute_function_with_boxes(name, func): +def make_execute_function(name, func): # Make a wrapper for 'func'. The func is a simple bhimpl_xxx function # from the BlackholeInterpreter class. The wrapper is a new function # that receives and returns boxed values. @@ -454,8 +460,22 @@ execute_varargs._annspecialcase_ = 'specialize:arg(2)' -def execute_nonspec(cpu, metainterp, opnum, argboxes, descr=None): - +def execute_nonspec_const(cpu, metainterp, opnum, argboxes, descr=None, + type='i'): +if type == 'i': +return ConstInt(_execute_nonspec(cpu, metainterp, opnum, argboxes, + descr, 'i')) +elif type == 'f': +return ConstFloat(_execute_nonspec(cpu, metainterp, opnum, argboxes, + descr, 'f')) +elif type == 'r': +return ConstPtr(_execute_nonspec(cpu, metainterp, opnum, argboxes, + descr, 'r')) +
[pypy-commit] pypy optresult: hack enough to make the first test from optimizebasic pass
Author: Maciej Fijalkowski Branch: optresult Changeset: r74520:6dfe20d64577 Date: 2014-11-14 10:44 +0200 http://bitbucket.org/pypy/pypy/changeset/6dfe20d64577/ Log:hack enough to make the first test from optimizebasic pass diff --git a/rpython/jit/metainterp/optimizeopt/intbounds.py b/rpython/jit/metainterp/optimizeopt/intbounds.py --- a/rpython/jit/metainterp/optimizeopt/intbounds.py +++ b/rpython/jit/metainterp/optimizeopt/intbounds.py @@ -6,7 +6,7 @@ from rpython.jit.metainterp.optimizeopt.optimizer import (Optimization, CONST_1, CONST_0, MODE_ARRAY, MODE_STR, MODE_UNICODE) from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method -from rpython.jit.metainterp.resoperation import rop +from rpython.jit.metainterp.resoperation import rop, AbstractResOp from rpython.jit.backend.llsupport import symbolic @@ -58,11 +58,8 @@ if b.has_lower and b.has_upper and b.lower == b.upper: v.make_constant(ConstInt(b.lower)) -try: -op = self.optimizer.producer[box] -except KeyError: -return -dispatch_bounds_ops(self, op) +if isinstance(box, AbstractResOp): +dispatch_bounds_ops(self, box) def optimize_GUARD_TRUE(self, op): self.emit_operation(op) @@ -83,7 +80,7 @@ self.emit_operation(op) if v1.intbound.known_ge(IntBound(0, 0)) and \ v2.intbound.known_ge(IntBound(0, 0)): -r = self.getvalue(op.result) +r = self.getvalue(op) mostsignificant = v1.intbound.upper | v2.intbound.upper r.intbound.intersect(IntBound(0, next_pow2_m1(mostsignificant))) @@ -95,7 +92,7 @@ v2 = self.getvalue(op.getarg(1)) self.emit_operation(op) -r = self.getvalue(op.result) +r = self.getvalue(op) if v2.is_constant(): val = v2.box.getint() if val >= 0: @@ -113,7 +110,7 @@ v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) self.emit_operation(op) -r = self.getvalue(op.result) +r = self.getvalue(op) b = v1.intbound.sub_bound(v2.intbound) if b.bounded(): r.intbound.intersect(b) @@ -122,7 +119,7 @@ v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) self.emit_operation(op) -r = self.getvalue(op.result) +r = self.getvalue(op) b = v1.intbound.add_bound(v2.intbound) if b.bounded(): r.intbound.intersect(b) @@ -131,7 +128,7 @@ v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) self.emit_operation(op) -r = self.getvalue(op.result) +r = self.getvalue(op) b = v1.intbound.mul_bound(v2.intbound) if b.bounded(): r.intbound.intersect(b) @@ -140,7 +137,7 @@ v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) self.emit_operation(op) -r = self.getvalue(op.result) +r = self.getvalue(op) r.intbound.intersect(v1.intbound.div_bound(v2.intbound)) def optimize_INT_MOD(self, op): @@ -158,7 +155,7 @@ self.emit_operation(op) if v2.is_constant(): val = v2.box.getint() -r = self.getvalue(op.result) +r = self.getvalue(op) if val < 0: if val == -sys.maxint-1: return # give up @@ -173,7 +170,7 @@ v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) self.emit_operation(op) -r = self.getvalue(op.result) +r = self.getvalue(op) b = v1.intbound.lshift_bound(v2.intbound) r.intbound.intersect(b) # intbound.lshift_bound checks for an overflow and if the @@ -192,7 +189,7 @@ self.make_constant_int(op.result, b.lower) else: self.emit_operation(op) -r = self.getvalue(op.result) +r = self.getvalue(op) r.intbound.intersect(b) def optimize_GUARD_NO_OVERFLOW(self, op): @@ -245,7 +242,7 @@ # optimize_GUARD_OVERFLOW, then InvalidLoop. op = op.copy_and_change(rop.INT_ADD) self.emit_operation(op) # emit the op -r = self.getvalue(op.result) +r = self.getvalue(op) r.intbound.intersect(resbound) def optimize_INT_SUB_OVF(self, op): @@ -258,7 +255,7 @@ if resbound.bounded(): op = op.copy_and_change(rop.INT_SUB) self.emit_operation(op) # emit the op -r = self.getvalue(op.result) +r = self.getvalue(op) r.intbound.intersect(resbound) def optimize_INT_MUL_OVF(self, op): @@ -268,7 +265,7 @@ if resbound.bounded(): op = op.copy_and_change(rop.INT_MUL) self.emit_operation(op) -r = self.getvalue(op.result) +r = self.getvalue(op) r.intbound.inter
[pypy-commit] pypy optresult: more hacking
Author: Maciej Fijalkowski Branch: optresult Changeset: r74522:555089bcfdc6 Date: 2014-11-14 18:18 +0200 http://bitbucket.org/pypy/pypy/changeset/555089bcfdc6/ Log:more hacking diff --git a/rpython/jit/metainterp/optimizeopt/intbounds.py b/rpython/jit/metainterp/optimizeopt/intbounds.py --- a/rpython/jit/metainterp/optimizeopt/intbounds.py +++ b/rpython/jit/metainterp/optimizeopt/intbounds.py @@ -73,9 +73,9 @@ v2 = self.getvalue(op.getarg(1)) if v1 is v2: if op.getopnum() == rop.INT_OR: -self.make_equal_to(op.result, v1) +self.make_equal_to(op, v1) else: -self.make_constant_int(op.result, 0) +self.make_constant_int(op, 0) return self.emit_operation(op) if v1.intbound.known_ge(IntBound(0, 0)) and \ @@ -179,7 +179,7 @@ # b.has_lower if b.has_lower and b.has_upper: # Synthesize the reverse op for optimize_default to reuse -self.pure(rop.INT_RSHIFT, [op.result, op.getarg(1)], op.getarg(0)) +self.pure(rop.INT_RSHIFT, [op, op.getarg(1)], op.getarg(0)) def optimize_INT_RSHIFT(self, op): v1 = self.getvalue(op.getarg(0)) @@ -187,7 +187,7 @@ b = v1.intbound.rshift_bound(v2.intbound) if b.has_lower and b.has_upper and b.lower == b.upper: # constant result (likely 0, for rshifts that kill all bits) -self.make_constant_int(op.result, b.lower) +self.make_constant_int(op, b.lower) else: self.emit_operation(op) r = self.getvalue(op) @@ -251,7 +251,7 @@ v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) if v1 is v2: -self.make_constant_int(op.result, 0) +self.make_constant_int(op, 0) return resbound = v1.intbound.sub_bound(v2.intbound) if resbound.bounded(): @@ -276,9 +276,9 @@ v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) if v1.intbound.known_lt(v2.intbound): -self.make_constant_int(op.result, 1) +self.make_constant_int(op, 1) elif v1.intbound.known_ge(v2.intbound) or v1 is v2: -self.make_constant_int(op.result, 0) +self.make_constant_int(op, 0) else: self.emit_operation(op) @@ -286,9 +286,9 @@ v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) if v1.intbound.known_gt(v2.intbound): -self.make_constant_int(op.result, 1) +self.make_constant_int(op, 1) elif v1.intbound.known_le(v2.intbound) or v1 is v2: -self.make_constant_int(op.result, 0) +self.make_constant_int(op, 0) else: self.emit_operation(op) @@ -296,9 +296,9 @@ v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) if v1.intbound.known_le(v2.intbound) or v1 is v2: -self.make_constant_int(op.result, 1) +self.make_constant_int(op, 1) elif v1.intbound.known_gt(v2.intbound): -self.make_constant_int(op.result, 0) +self.make_constant_int(op, 0) else: self.emit_operation(op) @@ -306,9 +306,9 @@ v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) if v1.intbound.known_ge(v2.intbound) or v1 is v2: -self.make_constant_int(op.result, 1) +self.make_constant_int(op, 1) elif v1.intbound.known_lt(v2.intbound): -self.make_constant_int(op.result, 0) +self.make_constant_int(op, 0) else: self.emit_operation(op) @@ -316,11 +316,11 @@ v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) if v1.intbound.known_gt(v2.intbound): -self.make_constant_int(op.result, 0) +self.make_constant_int(op, 0) elif v1.intbound.known_lt(v2.intbound): -self.make_constant_int(op.result, 0) +self.make_constant_int(op, 0) elif v1 is v2: -self.make_constant_int(op.result, 1) +self.make_constant_int(op, 1) else: self.emit_operation(op) @@ -328,18 +328,18 @@ v1 = self.getvalue(op.getarg(0)) v2 = self.getvalue(op.getarg(1)) if v1.intbound.known_gt(v2.intbound): -self.make_constant_int(op.result, 1) +self.make_constant_int(op, 1) elif v1.intbound.known_lt(v2.intbound): -self.make_constant_int(op.result, 1) +self.make_constant_int(op, 1) elif v1 is v2: -self.make_constant_int(op.result, 0) +self.make_constant_int(op, 0) else: self.emit_operation(op) def optimize_INT_FORCE_GE_ZERO(self, op): value = self.getvalue(op.getarg(0))
[pypy-commit] pypy optresult: whack until a third of test_optimizebasic passes, nothing to see there, really
Author: Maciej Fijalkowski Branch: optresult Changeset: r74523:2f3a6006bba2 Date: 2014-11-14 18:52 +0200 http://bitbucket.org/pypy/pypy/changeset/2f3a6006bba2/ Log:whack until a third of test_optimizebasic passes, nothing to see there, really diff --git a/rpython/jit/metainterp/optimizeopt/heap.py b/rpython/jit/metainterp/optimizeopt/heap.py --- a/rpython/jit/metainterp/optimizeopt/heap.py +++ b/rpython/jit/metainterp/optimizeopt/heap.py @@ -98,7 +98,7 @@ self._lazy_setfield = None if optheap.postponed_op: for a in op.getarglist(): -if a is optheap.postponed_op.result: +if a is optheap.postponed_op: optheap.emit_postponed_op() break optheap.next_optimization.propagate_forward(op) @@ -162,6 +162,7 @@ result, op.getdescr()) shortboxes.add_potential(getop, synthetic=True) elif op.result is not None: + shortboxes.add_potential(op) class BogusPureField(JitException): @@ -317,10 +318,10 @@ try: res_v = d[args] except KeyError: -d[args] = self.getvalue(op.result) +d[args] = self.getvalue(op) return False else: -self.make_equal_to(op.result, res_v) +self.make_equal_to(op, res_v) self.last_emitted_operation = REMOVED return True @@ -436,13 +437,13 @@ cf = self.field_cache(op.getdescr()) fieldvalue = cf.getfield_from_cache(self, structvalue) if fieldvalue is not None: -self.make_equal_to(op.result, fieldvalue) +self.make_equal_to(op, fieldvalue) return # default case: produce the operation structvalue.ensure_nonnull() self.emit_operation(op) # then remember the result of reading the field -fieldvalue = self.getvalue(op.result) +fieldvalue = self.getvalue(op) cf.remember_field_value(structvalue, fieldvalue, op) optimize_GETFIELD_GC_R = optimize_GETFIELD_GC_I optimize_GETFIELD_GC_F = optimize_GETFIELD_GC_I @@ -452,7 +453,7 @@ cf = self.field_cache(op.getdescr()) fieldvalue = cf.getfield_from_cache(self, structvalue) if fieldvalue is not None: -self.make_equal_to(op.result, fieldvalue) +self.make_equal_to(op, fieldvalue) return # default case: produce the operation structvalue.ensure_nonnull() @@ -461,7 +462,8 @@ optimize_GETFIELD_GC_PURE_F = optimize_GETFIELD_GC_PURE_I def optimize_SETFIELD_GC(self, op): -if self.has_pure_result(rop.GETFIELD_GC_PURE, [op.getarg(0)], +opnum = self.optimizer.getfield_pure_for_descr(op.getdescr()) +if self.has_pure_result(opnum, [op.getarg(0)], op.getdescr()): os.write(2, '[bogus _immutable_field_ declaration: %s]\n' % (op.getdescr().repr_of_descr())) @@ -480,7 +482,7 @@ cf = self.arrayitem_cache(op.getdescr(), indexvalue.box.getint()) fieldvalue = cf.getfield_from_cache(self, arrayvalue) if fieldvalue is not None: -self.make_equal_to(op.result, fieldvalue) +self.make_equal_to(op, fieldvalue) return else: # variable index, so make sure the lazy setarrayitems are done @@ -490,7 +492,7 @@ self.emit_operation(op) # the remember the result of reading the array item if cf is not None: -fieldvalue = self.getvalue(op.result) +fieldvalue = self.getvalue(op) cf.remember_field_value(arrayvalue, fieldvalue, op) optimize_GETARRAYITEM_GC_R = optimize_GETARRAYITEM_GC_I optimize_GETARRAYITEM_GC_F = optimize_GETARRAYITEM_GC_I @@ -505,7 +507,7 @@ cf = self.arrayitem_cache(op.getdescr(), indexvalue.box.getint()) fieldvalue = cf.getfield_from_cache(self, arrayvalue) if fieldvalue is not None: -self.make_equal_to(op.result, fieldvalue) +self.make_equal_to(op, fieldvalue) return else: # variable index, so make sure the lazy setarrayitems are done @@ -518,8 +520,8 @@ optimize_GETARRAYITEM_GC_PURE_F = optimize_GETARRAYITEM_GC_PURE_I def optimize_SETARRAYITEM_GC(self, op): -if self.has_pure_result(rop.GETARRAYITEM_GC_PURE, [op.getarg(0), - op.getarg(1)], +opnum = self.optimizer.getarrayitem_pure_for_descr(op.getdescr()) +if self.has_pure_result(opnum, [op.getarg(0), op.getarg(1)], op.getdescr()): os.write(2, '[bogus immutable array declaration: %s]\n' %
[pypy-commit] pypy ssa-flow: optimise remove_trivial_links()
Author: Ronan Lamy Branch: ssa-flow Changeset: r74526:5ad8e04f2740 Date: 2014-11-14 04:48 + http://bitbucket.org/pypy/pypy/changeset/5ad8e04f2740/ Log:optimise remove_trivial_links() diff --git a/rpython/flowspace/model.py b/rpython/flowspace/model.py --- a/rpython/flowspace/model.py +++ b/rpython/flowspace/model.py @@ -206,8 +206,6 @@ return uniqueitems([w for w in result if isinstance(w, Constant)]) def renamevariables(self, mapping): -for a in mapping: -assert isinstance(a, Variable), a self.inputargs = [mapping.get(a, a) for a in self.inputargs] for op in self.operations: op.args = [mapping.get(a, a) for a in op.args] diff --git a/rpython/translator/simplify.py b/rpython/translator/simplify.py --- a/rpython/translator/simplify.py +++ b/rpython/translator/simplify.py @@ -270,10 +270,15 @@ while vprev in renaming: vprev = renaming[vprev] renaming[vtarg] = vprev -target.renamevariables(renaming) -source.operations.extend(target.operations) -source.exitswitch = newexitswitch = target.exitswitch -exits = target.exits +def rename(v): +return renaming.get(v, v) +for op in target.operations: +source.operations.append(op.replace(renaming)) +source.exitswitch = newexitswitch = rename(target.exitswitch) +exits = [] +for exit in target.exits: +newexit = exit.copy(rename) +exits.append(newexit) source.recloseblock(*exits) if isinstance(newexitswitch, Constant) and newexitswitch != c_last_exception: exits = replace_exitswitch_by_constant(source, newexitswitch) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy ssa-flow: transform_dead_op_vars earlier
Author: Ronan Lamy Branch: ssa-flow Changeset: r74525:59a2022d0bd0 Date: 2014-11-14 04:27 + http://bitbucket.org/pypy/pypy/changeset/59a2022d0bd0/ Log:transform_dead_op_vars earlier diff --git a/rpython/translator/simplify.py b/rpython/translator/simplify.py --- a/rpython/translator/simplify.py +++ b/rpython/translator/simplify.py @@ -999,12 +999,11 @@ # all passes & simplify_graph all_passes = [ +transform_dead_op_vars, eliminate_empty_blocks, remove_assertion_errors, remove_trivial_links, coalesce_bool, -transform_dead_op_vars, -eliminate_empty_blocks, SSA_to_SSI, remove_identical_vars, transform_ovfcheck, ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy ssa-flow: transform_dead_op_vars() is compatible with SSA
Author: Ronan Lamy Branch: ssa-flow Changeset: r74524:c18905e4bc4f Date: 2014-11-14 04:05 + http://bitbucket.org/pypy/pypy/changeset/c18905e4bc4f/ Log:transform_dead_op_vars() is compatible with SSA diff --git a/rpython/flowspace/test/test_objspace.py b/rpython/flowspace/test/test_objspace.py --- a/rpython/flowspace/test/test_objspace.py +++ b/rpython/flowspace/test/test_objspace.py @@ -1291,6 +1291,17 @@ assert isinstance(link.args[0], Constant) assert link.args[0].value == 5 +def test_remove_dead_ops(self): +def f(): +a = [1] +b = (a, a) +c = type(b) +graph = self.codetest(f) +simplify_graph(graph) +assert graph.startblock.operations == [] +[link] = graph.startblock.exits +assert link.target is graph.returnblock + DATA = {'x': 5, 'y': 6} diff --git a/rpython/translator/simplify.py b/rpython/translator/simplify.py --- a/rpython/translator/simplify.py +++ b/rpython/translator/simplify.py @@ -1002,9 +1002,10 @@ eliminate_empty_blocks, remove_assertion_errors, remove_trivial_links, -SSA_to_SSI, coalesce_bool, transform_dead_op_vars, +eliminate_empty_blocks, +SSA_to_SSI, remove_identical_vars, transform_ovfcheck, simplify_exceptions, ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy ssa-flow: begin adapting remove_identical_vars() to SSA
Author: Ronan Lamy Branch: ssa-flow Changeset: r74527:2467d09a6d1e Date: 2014-11-14 21:29 + http://bitbucket.org/pypy/pypy/changeset/2467d09a6d1e/ Log:begin adapting remove_identical_vars() to SSA diff --git a/rpython/translator/simplify.py b/rpython/translator/simplify.py --- a/rpython/translator/simplify.py +++ b/rpython/translator/simplify.py @@ -7,14 +7,15 @@ import py from collections import defaultdict +from rpython.tool.algo.unionfind import UnionFind from rpython.flowspace.model import (Variable, Constant, c_last_exception, checkgraph, mkentrymap) from rpython.flowspace.operation import OverflowingOperation, op from rpython.rlib import rarithmetic from rpython.translator import unsimplify -from rpython.translator.backendopt import ssa from rpython.rtyper.lltypesystem import lloperation, lltype -from rpython.translator.backendopt.ssa import SSA_to_SSI +from rpython.translator.backendopt.ssa import ( +SSA_to_SSI, DataFlowFamilyBuilder) def get_graph(arg, translator): if isinstance(arg, Variable): @@ -550,6 +551,66 @@ if block.inputargs[i] not in read_vars: del block.inputargs[i] +class Representative(object): +def __init__(self, var): +self.rep = var + +def absorb(self, other): +pass + +def all_equal(lst): +first = lst[0] +return all(first == x for x in lst[1:]) + +def remove_identical_vars_SSA(graph): +"""When the same variable is passed multiple times into the next block, +pass it only once. This enables further optimizations by the annotator, +which otherwise doesn't realize that tests performed on one of the copies +of the variable also affect the other.""" +uf = UnionFind(Representative) +entrymap = mkentrymap(graph) +del entrymap[graph.startblock] +entrymap.pop(graph.returnblock, None) +entrymap.pop(graph.exceptblock, None) +inputs = {} +for block, links in entrymap.items(): +phis = zip(block.inputargs, zip(*[link.args for link in links])) +inputs[block] = phis + +def trivial_phis(block): +phis = inputs[block] +to_remove = [] +for i, (input, phi_args) in enumerate(phis): +new_args = [uf.find_rep(arg) for arg in phi_args] +if all_equal(new_args): +uf.union(new_args[0], input) +to_remove.append(i) +for i in reversed(to_remove): +del phis[i] +return bool(to_remove) + +progress = True +while progress: +progress = False +for block in inputs: +if trivial_phis(block): +progress = True + +renaming = {key: uf[key].rep for key in uf} +for block, links in entrymap.items(): +if inputs[block]: +new_inputs, new_args = zip(*inputs[block]) +new_args = map(list, zip(*new_args)) +else: +new_inputs = [] +new_args = [[] for _ in links] +block.inputargs = new_inputs +assert len(links) == len(new_args) +for link, args in zip(links, new_args): +link.args = args +for block in graph.iterblocks(): +block.renamevariables(renaming) + def remove_identical_vars(graph): """When the same variable is passed multiple times into the next block, pass it only once. This enables further optimizations by the annotator, @@ -1009,8 +1070,8 @@ remove_assertion_errors, remove_trivial_links, coalesce_bool, +remove_identical_vars_SSA, SSA_to_SSI, -remove_identical_vars, transform_ovfcheck, simplify_exceptions, transform_xxxitem, ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Optimize mmap slicing with step != 1
Author: Alex Gaynor Branch: Changeset: r74528:9e48410d1e31 Date: 2014-11-14 16:43 -0800 http://bitbucket.org/pypy/pypy/changeset/9e48410d1e31/ Log:Optimize mmap slicing with step != 1 diff --git a/pypy/module/mmap/interp_mmap.py b/pypy/module/mmap/interp_mmap.py --- a/pypy/module/mmap/interp_mmap.py +++ b/pypy/module/mmap/interp_mmap.py @@ -5,6 +5,7 @@ from rpython.rlib import rmmap, rarithmetic from rpython.rlib.buffer import Buffer from rpython.rlib.rmmap import RValueError, RTypeError, RMMapError +from rpython.rlib.rstring import StringBuilder if rmmap.HAVE_LARGEFILE_SUPPORT: OFF_T = rarithmetic.r_longlong @@ -163,17 +164,18 @@ self.check_valid() space = self.space -start, stop, step = space.decode_index(w_index, self.mmap.size) +start, stop, step, length = space.decode_index4(w_index, self.mmap.size) if step == 0: # index only return space.wrap(self.mmap.getitem(start)) elif step == 1: if stop - start < 0: return space.wrap("") -return space.wrap(self.mmap.getslice(start, stop - start)) +return space.wrap(self.mmap.getslice(start, length)) else: -res = "".join([self.mmap.getitem(i) - for i in range(start, stop, step)]) -return space.wrap(res) +b = StringBuilder(length) +for i in range(start, stop, step): +b.append(self.mmap.getitem(i)) +return space.wrap(b.build()) def descr_setitem(self, w_index, w_value): space = self.space ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy ssa-flow: fix remove_identical_vars_SSA()
Author: Ronan Lamy Branch: ssa-flow Changeset: r74529:18a5e66199ad Date: 2014-11-15 01:39 + http://bitbucket.org/pypy/pypy/changeset/18a5e66199ad/ Log:fix remove_identical_vars_SSA() diff --git a/rpython/flowspace/test/test_objspace.py b/rpython/flowspace/test/test_objspace.py --- a/rpython/flowspace/test/test_objspace.py +++ b/rpython/flowspace/test/test_objspace.py @@ -1302,6 +1302,16 @@ [link] = graph.startblock.exits assert link.target is graph.returnblock +def test_not_combine(self): +def f(n): +t = not n +if not n: +t += 1 +return t +graph = self.codetest(f) +simplify_graph(graph) +assert self.all_operations(graph) == {'bool': 1, 'inplace_add': 1} + DATA = {'x': 5, 'y': 6} diff --git a/rpython/translator/simplify.py b/rpython/translator/simplify.py --- a/rpython/translator/simplify.py +++ b/rpython/translator/simplify.py @@ -562,6 +562,9 @@ first = lst[0] return all(first == x for x in lst[1:]) +def isspecialvar(v): +return isinstance(v, Variable) and v._name in ('last_exception_', 'last_exc_value_') + def remove_identical_vars_SSA(graph): """When the same variable is passed multiple times into the next block, pass it only once. This enables further optimizations by the annotator, @@ -577,14 +580,22 @@ phis = zip(block.inputargs, zip(*[link.args for link in links])) inputs[block] = phis -def trivial_phis(block): +def simplify_phis(block): phis = inputs[block] to_remove = [] +unique_phis = {} for i, (input, phi_args) in enumerate(phis): new_args = [uf.find_rep(arg) for arg in phi_args] -if all_equal(new_args): +if all_equal(new_args) and not isspecialvar(new_args[0]): uf.union(new_args[0], input) to_remove.append(i) +else: +t = tuple(new_args) +if t in unique_phis: +uf.union(unique_phis[t], input) +to_remove.append(i) +else: +unique_phis[t] = input for i in reversed(to_remove): del phis[i] return bool(to_remove) @@ -593,7 +604,7 @@ while progress: progress = False for block in inputs: -if trivial_phis(block): +if simplify_phis(block): progress = True renaming = {key: uf[key].rep for key in uf} @@ -637,7 +648,7 @@ #when for all possible incoming paths they would get twice the same #value (this is really the purpose of remove_identical_vars()). # -builder = ssa.DataFlowFamilyBuilder(graph) +builder = DataFlowFamilyBuilder(graph) variable_families = builder.get_variable_families() # vertical removal while True: if not builder.merge_identical_phi_nodes():# horizontal removal @@ -732,7 +743,7 @@ # NB. this assumes RPythonicity: we can only iterate over something # that has a len(), and this len() cannot change as long as we are # using the iterator. -builder = ssa.DataFlowFamilyBuilder(graph) +builder = DataFlowFamilyBuilder(graph) variable_families = builder.get_variable_families() c_append = Constant('append') newlist_v = {} ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy ssa-flow: UnionFind: ensure meaningful result when absorb() isn't commutative
Author: Ronan Lamy Branch: ssa-flow Changeset: r74530:4ee0a64a020b Date: 2014-11-15 02:59 + http://bitbucket.org/pypy/pypy/changeset/4ee0a64a020b/ Log:UnionFind: ensure meaningful result when absorb() isn't commutative diff --git a/rpython/tool/algo/test/test_unionfind.py b/rpython/tool/algo/test/test_unionfind.py --- a/rpython/tool/algo/test/test_unionfind.py +++ b/rpython/tool/algo/test/test_unionfind.py @@ -18,6 +18,17 @@ uf.find(2) for i in xrange(2, 20, 2): uf.union(i, 2) -assert len(state) == 2 # we have exactly 2 partitions +assert len(state) == 2 # we have exactly 2 partitions +def test_asymmetric_absorb(): +class Info(object): +def __init__(self, obj): +self.values = [obj] +def absorb(self, other): +self.values += other.values + +uf = UnionFind(Info) +uf.union(2, 3) +uf.union(1, 2) +assert uf[1].values == uf[2].values == uf[3].values == [1, 2, 3] diff --git a/rpython/tool/algo/unionfind.py b/rpython/tool/algo/unionfind.py --- a/rpython/tool/algo/unionfind.py +++ b/rpython/tool/algo/unionfind.py @@ -72,19 +72,16 @@ if rep1 is rep2: return new1 or new2, rep1, info1 -w1 = self.weight[rep1] -w2 = self.weight[rep2] - -w = w1 + w2 - -if w1 < w2: -rep1, rep2, info1, info2, = rep2, rep1, info2, info1 - if info1 is not None: info1.absorb(info2) +w1 = self.weight[rep1] +w2 = self.weight[rep2] +w = w1 + w2 +if w1 < w2: +rep1, rep2 = rep2, rep1 + self.link_to_parent[rep2] = rep1 - del self.weight[rep2] del self.root_info[rep2] ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy ssa-flow: coalesce_bool() sort of requires SSI, actually
Author: Ronan Lamy Branch: ssa-flow Changeset: r74531:198df09019ba Date: 2014-11-15 05:16 + http://bitbucket.org/pypy/pypy/changeset/198df09019ba/ Log:coalesce_bool() sort of requires SSI, actually diff --git a/rpython/translator/simplify.py b/rpython/translator/simplify.py --- a/rpython/translator/simplify.py +++ b/rpython/translator/simplify.py @@ -1080,9 +1080,9 @@ eliminate_empty_blocks, remove_assertion_errors, remove_trivial_links, -coalesce_bool, remove_identical_vars_SSA, SSA_to_SSI, +coalesce_bool, transform_ovfcheck, simplify_exceptions, transform_xxxitem, ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy ssa-flow: remove_trivial_links() does not need to rename anything if done after remove_identical_vars()
Author: Ronan Lamy Branch: ssa-flow Changeset: r74532:bd556294573d Date: 2014-11-15 05:53 + http://bitbucket.org/pypy/pypy/changeset/bd556294573d/ Log:remove_trivial_links() does not need to rename anything if done after remove_identical_vars() diff --git a/rpython/translator/simplify.py b/rpython/translator/simplify.py --- a/rpython/translator/simplify.py +++ b/rpython/translator/simplify.py @@ -250,42 +250,32 @@ def remove_trivial_links(graph): """Remove trivial links by merging their source and target blocks -A link is trivial if it only renames variables, is the single exit of its +A link is trivial if it has no arguments, is the single exit of its source and the single parent of its target. """ entrymap = mkentrymap(graph) block = graph.startblock seen = set([block]) stack = list(block.exits) -renaming = {} while stack: link = stack.pop() if link.target in seen: continue source = link.prevblock target = link.target -if (source.exitswitch is None and len(entrymap[target]) == 1 and +if (not link.args and source.exitswitch is None and +len(entrymap[target]) == 1 and target.exits): # stop at the returnblock assert len(source.exits) == 1 -for vprev, vtarg in zip(link.args, target.inputargs): -while vprev in renaming: -vprev = renaming[vprev] -renaming[vtarg] = vprev def rename(v): return renaming.get(v, v) -for op in target.operations: -source.operations.append(op.replace(renaming)) -source.exitswitch = newexitswitch = rename(target.exitswitch) -exits = [] -for exit in target.exits: -newexit = exit.copy(rename) -exits.append(newexit) -source.recloseblock(*exits) +source.operations.extend(target.operations) +source.exitswitch = newexitswitch = target.exitswitch +source.recloseblock(*target.exits) if isinstance(newexitswitch, Constant) and newexitswitch != c_last_exception: exits = replace_exitswitch_by_constant(source, newexitswitch) -stack.extend(exits) +stack.extend(source.exits) else: -target.renamevariables(renaming) seen.add(target) stack.extend(target.exits) @@ -1079,8 +1069,8 @@ transform_dead_op_vars, eliminate_empty_blocks, remove_assertion_errors, +remove_identical_vars_SSA, remove_trivial_links, -remove_identical_vars_SSA, SSA_to_SSI, coalesce_bool, transform_ovfcheck, ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit