Author: Carl Friedrich Bolz <[email protected]>
Branch: better-storesink
Changeset: r87153:ea93a553b7a0
Date: 2016-09-06 16:35 +0200
http://bitbucket.org/pypy/pypy/changeset/ea93a553b7a0/
Log: actually super easy: support CSE on loop-invariant operations (SSA
makes this simple)
diff --git a/rpython/translator/backendopt/cse.py
b/rpython/translator/backendopt/cse.py
--- a/rpython/translator/backendopt/cse.py
+++ b/rpython/translator/backendopt/cse.py
@@ -14,8 +14,12 @@
except AttributeError:
return True
-def cse_graph(graph):
- return CSE([graph]).transform(graph)
+def common_subexpression_elimination(t, graphs=None):
+ if graphs is None:
+ graphs = t.graphs
+ cse = CSE(t)
+ for graph in graphs:
+ cse.transform(graph)
def can_fold(op):
return getattr(llop, op.opname).canfold
@@ -38,12 +42,16 @@
self.heapcache.copy())
- def merge(self, firstlink, tuples):
+ def merge(self, firstlink, tuples, backedge):
purecache = {}
block = firstlink.target
# copy all operations that exist in *all* blocks over. need to add a
new
# inputarg if the result is really a variable
+ # note that a backedge is not a problem for regular pure operations:
+ # since the argument is a phi node iff it is not loop invariant,
+ # copying things over is always save (yay SSA form!)
+
# try non-straight merges
for argindex, inputarg in enumerate(block.inputargs):
# bit slow, but probably ok
@@ -94,6 +102,10 @@
# ______________________
# merge heapcache
heapcache = {}
+ if backedge:
+ # can't deal with heapcache and backedges yet
+ return Cache(
+ self.variable_families, self.analyzer, purecache,
heapcache)
# try non-straight merges
for argindex, inputarg in enumerate(block.inputargs):
@@ -200,14 +212,14 @@
self.purecache[key] = op.result
return added_some_same_as
-def _merge(tuples, variable_families, analyzer):
+def _merge(tuples, variable_families, analyzer, backedge=False):
if not tuples:
return Cache(variable_families, analyzer)
if len(tuples) == 1:
(link, cache), = tuples
return cache.copy()
firstlink, firstcache = tuples[0]
- return firstcache.merge(firstlink, tuples)
+ return firstcache.merge(firstlink, tuples, backedge)
class CSE(object):
def __init__(self, translator):
@@ -226,17 +238,15 @@
while todo:
block = todo.popleft()
- can_cache = True
+ backedge = False
for link in entrymap[block]:
if link in backedges:
- can_cache = False
+ backedge = True
+ break
if block.operations:
- if not can_cache:
- cache = Cache(variable_families, self.analyzer)
- else:
- cache = _merge(
- caches_to_merge[block], variable_families,
self.analyzer)
+ cache = _merge(
+ caches_to_merge[block], variable_families, self.analyzer,
backedge)
changed_block = cache.cse_block(block)
added_some_same_as = changed_block or added_some_same_as
done.add(block)
diff --git a/rpython/translator/backendopt/test/test_cse.py
b/rpython/translator/backendopt/test/test_cse.py
--- a/rpython/translator/backendopt/test/test_cse.py
+++ b/rpython/translator/backendopt/test/test_cse.py
@@ -269,3 +269,13 @@
self.check(f, [int], getfield=1)
+ def test_loopinvariant(self):
+ def f(i):
+ x = i + 1
+ res = 0
+ while x:
+ x -= 1
+ res += i + 1
+ return res
+ self.check(f, [int], int_add=2)
+
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit