PageRenderTime 706ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/rpython/translator/backendopt/tailrecursion.py

https://bitbucket.org/pypy/pypy/
Python | 33 lines | 29 code | 3 blank | 1 comment | 4 complexity | ca2918a06ba06f5342209d6a5374cbe1 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. from rpython.flowspace.model import mkentrymap, checkgraph
  2. # this transformation is very academical -- I had too much time
  3. def _remove_tail_call(translator, graph, block):
  4. print "removing tail call"
  5. assert len(block.exits) == 1
  6. assert block.exits[0].target is graph.returnblock
  7. assert block.operations[-1].result == block.exits[0].args[0]
  8. op = block.operations[-1]
  9. block.operations = block.operations[:-1]
  10. block.exits[0].args = op.args[1:]
  11. block.exits[0].target = graph.startblock
  12. def remove_tail_calls_to_self(translator, graph):
  13. entrymap = mkentrymap(graph)
  14. changed = False
  15. for link in entrymap[graph.returnblock]:
  16. block = link.prevblock
  17. if (len(block.exits) == 1 and
  18. len(block.operations) > 0 and
  19. block.operations[-1].opname == 'direct_call' and
  20. block.operations[-1].result == link.args[0]):
  21. print "getgraph", graph
  22. if graph is graph:
  23. _remove_tail_call(translator, graph, block)
  24. changed = True
  25. if changed:
  26. from rpython.translator import simplify
  27. checkgraph(graph)
  28. simplify.remove_identical_vars(graph)
  29. simplify.eliminate_empty_blocks(graph)
  30. simplify.join_blocks(graph)