PageRenderTime 40ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/rpython/translator/backendopt/all.py

https://bitbucket.org/pypy/pypy/
Python | 172 lines | 135 code | 29 blank | 8 comment | 33 complexity | 277fc7bb369540703651f7b6c61ea27e MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. from rpython.translator.backendopt import removenoops
  2. from rpython.translator.backendopt import inline
  3. from rpython.translator.backendopt.malloc import remove_mallocs
  4. from rpython.translator.backendopt.constfold import constant_fold_graph
  5. from rpython.translator.backendopt.stat import print_statistics
  6. from rpython.translator.backendopt.merge_if_blocks import merge_if_blocks
  7. from rpython.translator import simplify
  8. from rpython.translator.backendopt import mallocprediction
  9. from rpython.translator.backendopt.removeassert import remove_asserts
  10. from rpython.translator.backendopt.support import log
  11. from rpython.translator.backendopt.storesink import storesink_graph
  12. from rpython.translator.backendopt import gilanalysis
  13. from rpython.flowspace.model import checkgraph
  14. INLINE_THRESHOLD_FOR_TEST = 33
  15. def get_function(dottedname):
  16. parts = dottedname.split('.')
  17. module = '.'.join(parts[:-1])
  18. name = parts[-1]
  19. try:
  20. mod = __import__(module, {}, {}, ['__doc__'])
  21. except ImportError as e:
  22. raise Exception("Import error loading %s: %s" % (dottedname, e))
  23. try:
  24. func = getattr(mod, name)
  25. except AttributeError:
  26. raise Exception("Function %s not found in module" % dottedname)
  27. return func
  28. def backend_optimizations(translator, graphs=None, secondary=False,
  29. inline_graph_from_anywhere=False, **kwds):
  30. # sensible keywords are
  31. # inline_threshold, mallocs
  32. # merge_if_blocks, constfold, heap2stack
  33. # clever_malloc_removal, remove_asserts
  34. config = translator.config.translation.backendopt.copy(as_default=True)
  35. config.set(**kwds)
  36. if graphs is None:
  37. graphs = translator.graphs
  38. for graph in graphs:
  39. assert not hasattr(graph, '_seen_by_the_backend')
  40. if config.print_statistics:
  41. print "before optimizations:"
  42. print_statistics(translator.graphs[0], translator, "per-graph.txt")
  43. if config.remove_asserts:
  44. constfold(config, graphs)
  45. remove_asserts(translator, graphs)
  46. if config.really_remove_asserts:
  47. for graph in graphs:
  48. removenoops.remove_debug_assert(graph)
  49. # the dead operations will be killed by the remove_obvious_noops below
  50. # remove obvious no-ops
  51. def remove_obvious_noops():
  52. for graph in graphs:
  53. removenoops.remove_same_as(graph)
  54. simplify.eliminate_empty_blocks(graph)
  55. simplify.transform_dead_op_vars(graph, translator)
  56. removenoops.remove_duplicate_casts(graph, translator)
  57. if config.print_statistics:
  58. print "after no-op removal:"
  59. print_statistics(translator.graphs[0], translator)
  60. remove_obvious_noops()
  61. if config.inline or config.mallocs:
  62. heuristic = get_function(config.inline_heuristic)
  63. if config.inline:
  64. threshold = config.inline_threshold
  65. else:
  66. threshold = 0
  67. inline_malloc_removal_phase(config, translator, graphs,
  68. threshold,
  69. inline_heuristic=heuristic,
  70. inline_graph_from_anywhere=inline_graph_from_anywhere)
  71. constfold(config, graphs)
  72. if config.clever_malloc_removal:
  73. threshold = config.clever_malloc_removal_threshold
  74. heuristic = get_function(config.clever_malloc_removal_heuristic)
  75. log.inlineandremove("phase with threshold factor: %s" % threshold)
  76. log.inlineandremove("heuristic: %s.%s" % (heuristic.__module__,
  77. heuristic.__name__))
  78. count = mallocprediction.clever_inlining_and_malloc_removal(
  79. translator, graphs,
  80. threshold = threshold,
  81. heuristic=heuristic)
  82. log.inlineandremove("removed %d simple mallocs in total" % count)
  83. constfold(config, graphs)
  84. if config.print_statistics:
  85. print "after clever inlining and malloc removal"
  86. print_statistics(translator.graphs[0], translator)
  87. if config.storesink:
  88. for graph in graphs:
  89. storesink_graph(graph)
  90. if config.profile_based_inline and not secondary:
  91. threshold = config.profile_based_inline_threshold
  92. heuristic = get_function(config.profile_based_inline_heuristic)
  93. inline.instrument_inline_candidates(graphs, threshold)
  94. counters = translator.driver_instrument_result(
  95. config.profile_based_inline)
  96. n = len(counters)
  97. def call_count_pred(label):
  98. if label >= n:
  99. return False
  100. return counters[label] > 250 # xxx introduce an option for this
  101. inline_malloc_removal_phase(config, translator, graphs,
  102. threshold,
  103. inline_heuristic=heuristic,
  104. call_count_pred=call_count_pred)
  105. constfold(config, graphs)
  106. if config.merge_if_blocks:
  107. log.mergeifblocks("starting to merge if blocks")
  108. for graph in graphs:
  109. merge_if_blocks(graph, translator.config.translation.verbose)
  110. if config.print_statistics:
  111. print "after if-to-switch:"
  112. print_statistics(translator.graphs[0], translator)
  113. remove_obvious_noops()
  114. for graph in graphs:
  115. checkgraph(graph)
  116. gilanalysis.analyze(graphs, translator)
  117. def constfold(config, graphs):
  118. if config.constfold:
  119. for graph in graphs:
  120. constant_fold_graph(graph)
  121. def inline_malloc_removal_phase(config, translator, graphs, inline_threshold,
  122. inline_heuristic,
  123. call_count_pred=None,
  124. inline_graph_from_anywhere=False):
  125. # inline functions in each other
  126. if inline_threshold:
  127. log.inlining("phase with threshold factor: %s" % inline_threshold)
  128. log.inlining("heuristic: %s.%s" % (inline_heuristic.__module__,
  129. inline_heuristic.__name__))
  130. inline.auto_inline_graphs(translator, graphs, inline_threshold,
  131. heuristic=inline_heuristic,
  132. call_count_pred=call_count_pred,
  133. inline_graph_from_anywhere=inline_graph_from_anywhere)
  134. if config.print_statistics:
  135. print "after inlining:"
  136. print_statistics(translator.graphs[0], translator)
  137. # vaporize mallocs
  138. if config.mallocs:
  139. log.malloc("starting malloc removal")
  140. remove_mallocs(translator, graphs)
  141. if config.print_statistics:
  142. print "after malloc removal:"
  143. print_statistics(translator.graphs[0], translator)