[pypy-commit] pypy default: Made the graphanalzyer code faster.
alex_gaynor
noreply at buildbot.pypy.org
Sun Dec 16 20:13:56 CET 2012
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch:
Changeset: r59463:a8e0bae2f603
Date: 2012-12-16 10:51 -0800
http://bitbucket.org/pypy/pypy/changeset/a8e0bae2f603/
Log: Made the graphanalzyer code faster.
It now requires less copying, and bails out sooner upon realizing
that a result includes everything.
diff --git a/pypy/translator/backendopt/graphanalyze.py b/pypy/translator/backendopt/graphanalyze.py
--- a/pypy/translator/backendopt/graphanalyze.py
+++ b/pypy/translator/backendopt/graphanalyze.py
@@ -12,10 +12,6 @@
# method overridden by subclasses
@staticmethod
- def join_two_results(result1, result2):
- raise NotImplementedError("abstract base class")
-
- @staticmethod
def bottom_result():
raise NotImplementedError("abstract base class")
@@ -28,6 +24,22 @@
# only an optimization, safe to always return False
return False
+ @staticmethod
+ def result_builder():
+ raise NotImplementedError("abstract base class")
+
+ @staticmethod
+ def add_to_result(result, other):
+ raise NotImplementedError("abstract base class")
+
+ @staticmethod
+ def finalize_builder(result):
+ raise NotImplementedError("abstract base class")
+
+ @staticmethod
+ def join_two_results(result1, result2):
+ raise NotImplementedError("abstract base class")
+
def analyze_simple_operation(self, op, graphinfo=None):
raise NotImplementedError("abstract base class")
@@ -59,12 +71,6 @@
# general methods
- def join_results(self, results):
- result = self.bottom_result()
- for sub in results:
- result = self.join_two_results(result, sub)
- return result
-
def compute_graph_info(self, graph):
return None
@@ -108,31 +114,51 @@
seen = DependencyTracker(self)
if not seen.enter(graph):
return seen.get_cached_result(graph)
- result = self.bottom_result()
+ result = self.result_builder()
graphinfo = self.compute_graph_info(graph)
for block in graph.iterblocks():
if block is graph.startblock:
- result = self.join_two_results(
- result, self.analyze_startblock(block, seen))
+ result = self.add_to_result(
+ result,
+ self.analyze_startblock(block, seen)
+ )
elif block is graph.exceptblock:
- result = self.join_two_results(
- result, self.analyze_exceptblock(block, seen))
- for op in block.operations:
- result = self.join_two_results(
- result, self.analyze(op, seen, graphinfo))
- for exit in block.exits:
- result = self.join_two_results(
- result, self.analyze_link(exit, seen))
+ result = self.add_to_result(
+ result,
+ self.analyze_exceptblock(block, seen)
+ )
+ if not self.is_top_result(result):
+ for op in block.operations:
+ result = self.add_to_result(
+ result,
+ self.analyze(op, seen, graphinfo)
+ )
+ if self.is_top_result(result):
+ break
+ if not self.is_top_result(result):
+ for exit in block.exits:
+ result = self.add_to_result(
+ result,
+ self.analyze_link(exit, seen)
+ )
+ if self.is_top_result(result):
+ break
if self.is_top_result(result):
break
+ result = self.finalize_builder(result)
seen.leave_with(result)
return result
def analyze_indirect_call(self, graphs, seen=None):
- results = []
+ result = self.result_builder()
for graph in graphs:
- results.append(self.analyze_direct_call(graph, seen))
- return self.join_results(results)
+ result = self.add_to_result(
+ result,
+ self.analyze_direct_call(graph, seen)
+ )
+ if self.is_top_result(result):
+ break
+ return self.finalize_builder(result)
def analyze_oosend(self, TYPE, name, seen=None):
graphs = TYPE._lookup_graphs(name)
@@ -210,18 +236,23 @@
"""generic way to analyze graphs: recursively follow it until the first
operation is found on which self.analyze_simple_operation returns True"""
- @staticmethod
- def join_two_results(result1, result2):
- return result1 or result2
+ def bottom_result(self):
+ return False
- @staticmethod
- def is_top_result(result):
+ def top_result(self):
+ return True
+
+ def is_top_result(self, result):
return result
- @staticmethod
- def bottom_result():
+ def result_builder(self):
return False
- @staticmethod
- def top_result():
- return True
+ def add_to_result(self, result, other):
+ return self.join_two_results(result, other)
+
+ def finalize_builder(self, result):
+ return result
+
+ def join_two_results(self, result1, result2):
+ return result1 or result2
diff --git a/pypy/translator/backendopt/writeanalyze.py b/pypy/translator/backendopt/writeanalyze.py
--- a/pypy/translator/backendopt/writeanalyze.py
+++ b/pypy/translator/backendopt/writeanalyze.py
@@ -5,37 +5,36 @@
top_set = object()
empty_set = frozenset()
+
class WriteAnalyzer(graphanalyze.GraphAnalyzer):
+ def bottom_result(self):
+ return empty_set
- @staticmethod
- def join_two_results(result1, result2):
- if result1 is top_set:
+ def top_result(self):
+ return top_set
+
+ def is_top_result(self, result):
+ return result is top_set
+
+ def result_builder(self):
+ return set()
+
+ def add_to_result(self, result, other):
+ if other is top_set:
return top_set
- if result2 is top_set:
+ result.update(other)
+ return result
+
+ def finalize_builder(self, result):
+ if result is top_set:
+ return result
+ return frozenset(result)
+
+ def join_two_results(self, result1, result2):
+ if result1 is top_set or result2 is top_set:
return top_set
return result1.union(result2)
- @staticmethod
- def join_results(results):
- result = set()
- for res in results:
- if res is top_set:
- return top_set
- result |= res
- return frozenset(result)
-
- @staticmethod
- def bottom_result():
- return empty_set
-
- @staticmethod
- def top_result():
- return top_set
-
- @staticmethod
- def is_top_result(result):
- return result is top_set
-
def analyze_simple_operation(self, op, graphinfo):
if op.opname in ("setfield", "oosetfield"):
if graphinfo is None or not graphinfo.is_fresh_malloc(op.args[0]):
More information about the pypy-commit
mailing list