migen/fhdl/tools: speed up group_by_targets (halves the mixxeo runtime)
authorRobert Jordens <jordens@gmail.com>
Fri, 6 Dec 2013 22:04:57 +0000 (15:04 -0700)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Tue, 17 Dec 2013 17:40:49 +0000 (18:40 +0100)
migen/fhdl/tools.py

index 00c9932fc7746806f0e7e8e91c6876e6d0801c92..47ef253ba8a25ad65e4a61babcc9a95983492fd4 100644 (file)
@@ -45,23 +45,23 @@ def _resort_statements(ol):
 
 def group_by_targets(sl):
        groups = []
-       for statement_order, statement in enumerate(flat_iteration(sl)):
-               targets = list_targets(statement)
-
-               chk_groups = [(targets.isdisjoint(g[0]), g) for g in groups]
-               merge_groups = [g for dj, g in chk_groups if not dj]
-               groups = [g for dj, g in chk_groups if dj]
-
-               new_group = (set(targets), [(statement_order, statement)])
-
-               for g in merge_groups:
-                       new_group[0].update(g[0])
-                       new_group[1].extend(g[1])
-
-               groups.append(new_group)
-
-       return [(target, _resort_statements(stmts))
-               for target, stmts in groups]
+       seen = set()
+       for order, stmt in enumerate(flat_iteration(sl)):
+               targets = set(list_targets(stmt))
+               group = [(order, stmt)]
+               disjoint = targets.isdisjoint(seen)
+               seen |= targets
+               if not disjoint:
+                       groups, old_groups = [], groups
+                       for old_targets, old_group in old_groups:
+                               if targets.isdisjoint(old_targets):
+                                       groups.append((old_targets, old_group))
+                               else:
+                                       targets |= old_targets
+                                       group += old_group
+               groups.append((targets, group))
+       return [(targets, _resort_statements(stmts))
+               for targets, stmts in groups]
 
 def list_special_ios(f, ins, outs, inouts):
        r = set()