mirror of
https://github.com/python/cpython.git
synced 2025-10-27 11:44:39 +00:00
Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
POP_JUMP_IF_{TRUE,FALSE} and JUMP_IF_{TRUE,FALSE}_OR_POP. This avoids executing
a POP_TOP on each conditional and sometimes allows the peephole optimizer to
skip a JUMP_ABSOLUTE entirely. It speeds up list comprehensions significantly.
This commit is contained in:
parent
de28d6841e
commit
68d6852006
11 changed files with 228 additions and 178 deletions
|
|
@ -421,13 +421,11 @@ def visitIf(self, node):
|
|||
self.set_lineno(test)
|
||||
self.visit(test)
|
||||
nextTest = self.newBlock()
|
||||
self.emit('JUMP_IF_FALSE', nextTest)
|
||||
self.emit('POP_JUMP_IF_FALSE', nextTest)
|
||||
self.nextBlock()
|
||||
self.emit('POP_TOP')
|
||||
self.visit(suite)
|
||||
self.emit('JUMP_FORWARD', end)
|
||||
self.startBlock(nextTest)
|
||||
self.emit('POP_TOP')
|
||||
if node.else_:
|
||||
self.visit(node.else_)
|
||||
self.nextBlock(end)
|
||||
|
|
@ -446,15 +444,13 @@ def visitWhile(self, node):
|
|||
|
||||
self.set_lineno(node, force=True)
|
||||
self.visit(node.test)
|
||||
self.emit('JUMP_IF_FALSE', else_ or after)
|
||||
self.emit('POP_JUMP_IF_FALSE', else_ or after)
|
||||
|
||||
self.nextBlock()
|
||||
self.emit('POP_TOP')
|
||||
self.visit(node.body)
|
||||
self.emit('JUMP_ABSOLUTE', loop)
|
||||
|
||||
self.startBlock(else_) # or just the POPs if not else clause
|
||||
self.emit('POP_TOP')
|
||||
self.emit('POP_BLOCK')
|
||||
self.setups.pop()
|
||||
if node.else_:
|
||||
|
|
@ -525,26 +521,23 @@ def visitTest(self, node, jump):
|
|||
self.visit(child)
|
||||
self.emit(jump, end)
|
||||
self.nextBlock()
|
||||
self.emit('POP_TOP')
|
||||
self.visit(node.nodes[-1])
|
||||
self.nextBlock(end)
|
||||
|
||||
def visitAnd(self, node):
|
||||
self.visitTest(node, 'JUMP_IF_FALSE')
|
||||
self.visitTest(node, 'JUMP_IF_FALSE_OR_POP')
|
||||
|
||||
def visitOr(self, node):
|
||||
self.visitTest(node, 'JUMP_IF_TRUE')
|
||||
self.visitTest(node, 'JUMP_IF_TRUE_OR_POP')
|
||||
|
||||
def visitIfExp(self, node):
|
||||
endblock = self.newBlock()
|
||||
elseblock = self.newBlock()
|
||||
self.visit(node.test)
|
||||
self.emit('JUMP_IF_FALSE', elseblock)
|
||||
self.emit('POP_TOP')
|
||||
self.emit('POP_JUMP_IF_FALSE', elseblock)
|
||||
self.visit(node.then)
|
||||
self.emit('JUMP_FORWARD', endblock)
|
||||
self.nextBlock(elseblock)
|
||||
self.emit('POP_TOP')
|
||||
self.visit(node.else_)
|
||||
self.nextBlock(endblock)
|
||||
|
||||
|
|
@ -556,9 +549,8 @@ def visitCompare(self, node):
|
|||
self.emit('DUP_TOP')
|
||||
self.emit('ROT_THREE')
|
||||
self.emit('COMPARE_OP', op)
|
||||
self.emit('JUMP_IF_FALSE', cleanup)
|
||||
self.emit('JUMP_IF_FALSE_OR_POP', cleanup)
|
||||
self.nextBlock()
|
||||
self.emit('POP_TOP')
|
||||
# now do the last comparison
|
||||
if node.ops:
|
||||
op, code = node.ops[-1]
|
||||
|
|
@ -593,11 +585,7 @@ def visitListComp(self, node):
|
|||
|
||||
for start, cont, anchor in stack:
|
||||
if cont:
|
||||
skip_one = self.newBlock()
|
||||
self.emit('JUMP_FORWARD', skip_one)
|
||||
self.startBlock(cont)
|
||||
self.emit('POP_TOP')
|
||||
self.nextBlock(skip_one)
|
||||
self.nextBlock(cont)
|
||||
self.emit('JUMP_ABSOLUTE', start)
|
||||
self.startBlock(anchor)
|
||||
|
||||
|
|
@ -617,9 +605,8 @@ def visitListCompFor(self, node):
|
|||
def visitListCompIf(self, node, branch):
|
||||
self.set_lineno(node, force=True)
|
||||
self.visit(node.test)
|
||||
self.emit('JUMP_IF_FALSE', branch)
|
||||
self.emit('POP_JUMP_IF_FALSE', branch)
|
||||
self.newBlock()
|
||||
self.emit('POP_TOP')
|
||||
|
||||
def _makeClosure(self, gen, args):
|
||||
frees = gen.scope.get_free_vars()
|
||||
|
|
@ -665,11 +652,7 @@ def visitGenExprInner(self, node):
|
|||
|
||||
for start, cont, anchor, end in stack:
|
||||
if cont:
|
||||
skip_one = self.newBlock()
|
||||
self.emit('JUMP_FORWARD', skip_one)
|
||||
self.startBlock(cont)
|
||||
self.emit('POP_TOP')
|
||||
self.nextBlock(skip_one)
|
||||
self.nextBlock(cont)
|
||||
self.emit('JUMP_ABSOLUTE', start)
|
||||
self.startBlock(anchor)
|
||||
self.emit('POP_BLOCK')
|
||||
|
|
@ -702,9 +685,8 @@ def visitGenExprFor(self, node):
|
|||
def visitGenExprIf(self, node, branch):
|
||||
self.set_lineno(node, force=True)
|
||||
self.visit(node.test)
|
||||
self.emit('JUMP_IF_FALSE', branch)
|
||||
self.emit('POP_JUMP_IF_FALSE', branch)
|
||||
self.newBlock()
|
||||
self.emit('POP_TOP')
|
||||
|
||||
# exception related
|
||||
|
||||
|
|
@ -719,9 +701,8 @@ def visitAssert(self, node):
|
|||
# is a sort of renaming op.
|
||||
self.nextBlock()
|
||||
self.visit(node.test)
|
||||
self.emit('JUMP_IF_TRUE', end)
|
||||
self.emit('POP_JUMP_IF_TRUE', end)
|
||||
self.nextBlock()
|
||||
self.emit('POP_TOP')
|
||||
self.emit('LOAD_GLOBAL', 'AssertionError')
|
||||
if node.fail:
|
||||
self.visit(node.fail)
|
||||
|
|
@ -729,7 +710,6 @@ def visitAssert(self, node):
|
|||
else:
|
||||
self.emit('RAISE_VARARGS', 1)
|
||||
self.nextBlock(end)
|
||||
self.emit('POP_TOP')
|
||||
|
||||
def visitRaise(self, node):
|
||||
self.set_lineno(node)
|
||||
|
|
@ -772,9 +752,8 @@ def visitTryExcept(self, node):
|
|||
self.visit(expr)
|
||||
self.emit('COMPARE_OP', 'exception match')
|
||||
next = self.newBlock()
|
||||
self.emit('JUMP_IF_FALSE', next)
|
||||
self.emit('POP_JUMP_IF_FALSE', next)
|
||||
self.nextBlock()
|
||||
self.emit('POP_TOP')
|
||||
self.emit('POP_TOP')
|
||||
if target:
|
||||
self.visit(target)
|
||||
|
|
@ -787,8 +766,6 @@ def visitTryExcept(self, node):
|
|||
self.nextBlock(next)
|
||||
else:
|
||||
self.nextBlock()
|
||||
if expr: # XXX
|
||||
self.emit('POP_TOP')
|
||||
self.emit('END_FINALLY')
|
||||
if node.else_:
|
||||
self.nextBlock(lElse)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue