[pypy-commit] pypy arm-backend-2: merge up to 43861
bivab
noreply at buildbot.pypy.org
Fri Jun 24 17:39:50 CEST 2011
Author: David Schneider <david.schneider at picle.org>
Branch: arm-backend-2
Changeset: r45103:60ff2d1ca4bb
Date: 2011-06-24 10:00 +0200
http://bitbucket.org/pypy/pypy/changeset/60ff2d1ca4bb/
Log: merge up to 43861
diff --git a/pypy/doc/discussion/jit-profiler.rst b/pypy/doc/discussion/jit-profiler.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/discussion/jit-profiler.rst
@@ -0,0 +1,79 @@
+A JIT-aware profiler
+====================
+
+Goal: have a profiler which is aware of the PyPy JIT and which shows which
+percentage of the time have been spent in which loops.
+
+Long term goal: integrate the data collected by the profiler with the
+jitviewer.
+
+The idea is record an event in the PYPYLOG everytime we enter and exit a loop
+or a bridge.
+
+Expected output
+----------------
+
+[100] {jit-profile-enter
+loop1 # e.g. an entry bridge
+[101] jit-profile-enter}
+...
+[200] {jit-profile-enter
+loop0 # JUMP from loop1 to loop0
+[201] jit-profile-enter}
+...
+[500] {jit-profile-exit
+loop0 # e.g. because of a failing guard
+[501] jit-profile-exit}
+
+In this example, the exiting from loop1 is implicit because we are entering
+loop0. So, we spent 200-100=100 ticks in the entry bridge, and 500-200=300
+ticks in the actual loop.
+
+What to do about "inner" bridges?
+----------------------------------
+
+"Inner bridges" are those bridges which jump back to the loop where they
+originate from. There are two possible ways of dealing with them:
+
+ 1. we ignore them: we record when we enter the loop, but not when we jump to
+ a compiled inner bridge. The exit event will be recorded only in case of
+ a non-compiled guard failure or a JUMP to another loop
+
+ 2. we record the enter/exit of each inner bridge
+
+The disadvantage of solution (2) is that there are certain loops which takes
+bridges at everty single iteration. So, in this case we would record a huge
+number of events, possibly adding a lot of overhead and thus making the
+profiled data useless.
+
+
+Detecting the enter to/exit from a loop
+----------------------------------------
+
+Ways to enter:
+
+ - just after the tracing/compilation
+
+ - from the interpreter, if the loop has already been compiled
+
+ - from another loop, via a JUMP operation
+
+ - from a hot guard failure (which we ignore, in case we choose solution
+ (1) above)
+
+ - XXX: am I missing anything?
+
+Ways to exit:
+
+ - guard failure (entering blackhole)
+
+ - guard failure (jumping to a bridge) (ignored in case of solution (1))
+
+ - jump to another loop
+
+ - XXX: am I missing anything?
+
+
+About call_assembler: I think that at the beginning, we should just ignore
+call_assembler: the time spent inside the call will be accounted to the loop
+calling it.
diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py
--- a/pypy/jit/backend/test/runner_test.py
+++ b/pypy/jit/backend/test/runner_test.py
@@ -332,6 +332,30 @@
fail = self.cpu.execute_token(looptoken)
assert fail is faildescr
+ if self.cpu.supports_floats:
+ looptoken = LoopToken()
+ f0 = BoxFloat()
+ operations = [
+ ResOperation(rop.FINISH, [f0], None, descr=faildescr)
+ ]
+ self.cpu.compile_loop([f0], operations, looptoken)
+ value = longlong.getfloatstorage(-61.25)
+ self.cpu.set_future_value_float(0, value)
+ fail = self.cpu.execute_token(looptoken)
+ assert fail is faildescr
+ res = self.cpu.get_latest_value_float(0)
+ assert longlong.getrealfloat(res) == -61.25
+
+ looptoken = LoopToken()
+ operations = [
+ ResOperation(rop.FINISH, [constfloat(42.5)], None, descr=faildescr)
+ ]
+ self.cpu.compile_loop([], operations, looptoken)
+ fail = self.cpu.execute_token(looptoken)
+ assert fail is faildescr
+ res = self.cpu.get_latest_value_float(0)
+ assert longlong.getrealfloat(res) == 42.5
+
def test_execute_operations_in_env(self):
cpu = self.cpu
x = BoxInt(123)
diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -1843,8 +1843,9 @@
for i in range(len(locs)):
loc = locs[i]
if not isinstance(loc, RegLoc):
- if isinstance(loc, StackLoc) and loc.type == FLOAT:
- self.mc.MOVSD_xb(xmm0.value, loc.value)
+ if ((isinstance(loc, StackLoc) and loc.type == FLOAT) or
+ isinstance(loc, ConstFloatLoc)):
+ self.mc.MOVSD(xmm0, loc)
adr = self.fail_boxes_float.get_addr_for_num(i)
self.mc.MOVSD(heap(adr), xmm0)
else:
diff --git a/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py b/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py
--- a/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py
@@ -1662,3 +1662,20 @@
assert log.result == 300
loop, = log.loops_by_filename(self.filepath)
assert loop.match_by_id('shift', "") # optimized away
+
+ def test_division_to_rshift(self):
+ def main(b):
+ res = 0
+ a = 0
+ while a < 300:
+ assert a >= 0
+ assert 0 <= b <= 10
+ res = a/b # ID: div
+ a += 1
+ return res
+ #
+ log = self.run(main, [3], threshold=200)
+ #assert log.result == 149
+ loop, = log.loops_by_filename(self.filepath)
+ import pdb;pdb.set_trace()
+ assert loop.match_by_id('div', "") # optimized away
More information about the pypy-commit
mailing list