Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(4)

Unified Diff: Lib/compiler/pycodegen.py

Issue 20103: http://bugs.python.org/issue2459 -- speed up loops SVN Base: http://svn.python.org/view/*checkout*/python/trunk/
Patch Set: Created 9 months, 1 week ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side by-side-diff with in-line comments
Download patch
Index: Lib/compiler/pycodegen.py
===================================================================
--- Lib/compiler/pycodegen.py (revision 70087)
+++ Lib/compiler/pycodegen.py (working copy)
@@ -413,7 +413,7 @@
def visitIf(self, node):
end = self.newBlock()
numtests = len(node.tests)
- for i in range(numtests):
+ for i in range(numtests - 1):
test, suite = node.tests[i]
if is_constant_false(test):
# XXX will need to check generator stuff here
@@ -426,8 +426,22 @@
self.visit(suite)
self.emit('JUMP_FORWARD', end)
self.startBlock(nextTest)
- if node.else_:
- self.visit(node.else_)
+ # The last test can optimize a few things
+ test, suite = node.tests[numtests - 1]
+ if is_constant_false(test):
+ if node.else_:
+ self.visit(node.else_)
+ else:
+ self.set_lineno(test)
+ self.visit(test)
+ else_block = self.newBlock() if node.else_ else end
+ self.emit('POP_JUMP_IF_FALSE', else_block)
+ self.nextBlock()
+ self.visit(suite)
+ if node.else_:
+ self.emit('JUMP_FORWARD', end)
+ self.startBlock(else_block)
+ self.visit(node.else_)
self.nextBlock(end)
def visitWhile(self, node):
@@ -435,22 +449,26 @@
loop = self.newBlock()
else_ = self.newBlock()
-
+ body = self.newBlock()
+ tail = self.newBlock()
after = self.newBlock()
+
self.emit('SETUP_LOOP', after)
self.nextBlock(loop)
self.setups.push((LOOP, loop))
+ self.emit('JUMP_FORWARD', tail)
+ self.startBlock(body)
self.set_lineno(node, force=True)
- self.visit(node.test)
- self.emit('POP_JUMP_IF_FALSE', else_ or after)
- self.nextBlock()
self.visit(node.body)
- self.emit('JUMP_ABSOLUTE', loop)
- self.startBlock(else_) # or just the POPs if not else clause
+ self.nextBlock(tail)
+ self.visit(node.test)
+ self.emit('POP_JUMP_IF_TRUE', body)
+
+ self.nextBlock(else_) # or just the POPs if not else clause
self.emit('POP_BLOCK')
self.setups.pop()
if node.else_:
@@ -459,6 +477,8 @@
def visitFor(self, node):
start = self.newBlock()
+ body = self.newBlock()
+ tail = self.newBlock()
anchor = self.newBlock()
after = self.newBlock()
self.setups.push((LOOP, start))
@@ -470,10 +490,12 @@
self.nextBlock(start)
self.set_lineno(node, force=1)
- self.emit('FOR_ITER', anchor)
+ self.emit('JUMP_FORWARD', tail)
+ self.startBlock(body)
self.visit(node.assign)
self.visit(node.body)
- self.emit('JUMP_ABSOLUTE', start)
+ self.nextBlock(tail)
+ self.emit('FOR_ITER', body)
self.nextBlock(anchor)
self.emit('POP_BLOCK')
self.setups.pop()
@@ -571,42 +593,37 @@
self.emit('BUILD_LIST', 0)
stack = []
- for i, for_ in zip(range(len(node.quals)), node.quals):
- start, anchor = self.visit(for_)
- cont = None
+ for for_ in node.quals:
+ body, tail = self.visit(for_)
for if_ in for_.ifs:
- if cont is None:
- cont = self.newBlock()
- self.visit(if_, cont)
- stack.insert(0, (start, cont, anchor))
+ self.visit(if_, tail)
+ stack.insert(0, (for_, body, tail))
self.visit(node.expr)
self.emit('LIST_APPEND', len(node.quals) + 1)
- for start, cont, anchor in stack:
- if cont:
- self.nextBlock(cont)
- self.emit('JUMP_ABSOLUTE', start)
- self.startBlock(anchor)
+ for for_, body, tail in stack:
+ self.nextBlock(tail)
+ self.set_lineno(for_, force=True)
+ self.emit('FOR_ITER', body)
+ self.nextBlock()
def visitListCompFor(self, node):
- start = self.newBlock()
- anchor = self.newBlock()
+ body = self.newBlock()
+ tail = self.newBlock()
self.visit(node.list)
self.emit('GET_ITER')
- self.nextBlock(start)
- self.set_lineno(node, force=True)
- self.emit('FOR_ITER', anchor)
self.nextBlock()
+ self.emit('JUMP_FORWARD', tail)
+ self.nextBlock(body)
self.visit(node.assign)
- return start, anchor
+ return body, tail
def visitListCompIf(self, node, branch):
self.set_lineno(node, force=True)
self.visit(node.test)
self.emit('POP_JUMP_IF_FALSE', branch)
- self.newBlock()
def _makeClosure(self, gen, args):
frees = gen.scope.get_free_vars()
@@ -637,24 +654,21 @@
# setup list
stack = []
- for i, for_ in zip(range(len(node.quals)), node.quals):
- start, anchor, end = self.visit(for_)
- cont = None
+ for for_ in node.quals:
+ body, tail, end = self.visit(for_)
for if_ in for_.ifs:
- if cont is None:
- cont = self.newBlock()
- self.visit(if_, cont)
- stack.insert(0, (start, cont, anchor, end))
+ self.visit(if_, tail)
+ stack.insert(0, (for_, body, tail, end))
self.visit(node.expr)
self.emit('YIELD_VALUE')
self.emit('POP_TOP')
- for start, cont, anchor, end in stack:
- if cont:
- self.nextBlock(cont)
- self.emit('JUMP_ABSOLUTE', start)
- self.startBlock(anchor)
+ for for_, body, tail, end in stack:
+ self.nextBlock(tail)
+ self.set_lineno(for_, force=True)
+ self.emit('FOR_ITER', body)
+ self.nextBlock()
self.emit('POP_BLOCK')
self.setups.pop()
self.nextBlock(end)
@@ -663,7 +677,8 @@
def visitGenExprFor(self, node):
start = self.newBlock()
- anchor = self.newBlock()
+ body = self.newBlock()
+ tail = self.newBlock()
end = self.newBlock()
self.setups.push((LOOP, start))
@@ -676,11 +691,10 @@
self.emit('GET_ITER')
self.nextBlock(start)
- self.set_lineno(node, force=True)
- self.emit('FOR_ITER', anchor)
- self.nextBlock()
+ self.emit('JUMP_FORWARD', tail)
+ self.nextBlock(body)
self.visit(node.assign)
- return start, anchor, end
+ return body, tail, end
def visitGenExprIf(self, node, branch):
self.set_lineno(node, force=True)

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld r497