[pypy-commit] pypy stmgc-c7: Update "import_stmgc.py" to show which new files need to

2014-11-14 Thread arigo
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.

2014-11-14 Thread arigo
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

2014-11-14 Thread arigo
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

2014-11-14 Thread Raemi
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

2014-11-14 Thread bivab
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

2014-11-14 Thread fijal
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

2014-11-14 Thread fijal
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

2014-11-14 Thread fijal
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

2014-11-14 Thread fijal
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()

2014-11-14 Thread rlamy
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

2014-11-14 Thread rlamy
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

2014-11-14 Thread rlamy
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

2014-11-14 Thread rlamy
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

2014-11-14 Thread alex_gaynor
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()

2014-11-14 Thread rlamy
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

2014-11-14 Thread rlamy
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

2014-11-14 Thread rlamy
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()

2014-11-14 Thread rlamy
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