add python generator version of tree reduction
authorJacob Lifshay <programmerjake@gmail.com>
Fri, 25 Mar 2022 12:59:36 +0000 (05:59 -0700)
committerJacob Lifshay <programmerjake@gmail.com>
Fri, 25 Mar 2022 12:59:36 +0000 (05:59 -0700)
src/openpower/decoder/isa/tree_reduce/__init__.py [new file with mode: 0644]
src/openpower/decoder/isa/tree_reduce/generator.py [new file with mode: 0644]

diff --git a/src/openpower/decoder/isa/tree_reduce/__init__.py b/src/openpower/decoder/isa/tree_reduce/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/openpower/decoder/isa/tree_reduce/generator.py b/src/openpower/decoder/isa/tree_reduce/generator.py
new file mode 100644 (file)
index 0000000..be271b7
--- /dev/null
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: LGPL-3-or-later
+# Copyright 2022 Jacob Lifshay programmerjake@gmail.com
+
+""" Tree-based Reduction as a Python Generator.
+
+https://bugs.libre-soc.org/show_bug.cgi?id=697
+"""
+
+from openpower.util.text_tree_graph import Op, print_tree
+
+
+class Move(Op):
+    def __init__(self, out, in_):
+        super().__init__((out,), (in_,))
+
+
+class FAdd(Op):
+    def __init__(self, out, in0, in1):
+        super().__init__((out,), (in0, in1))
+
+
+def tree_reduce(bitmask, vl, remap=None, bin_op=FAdd):
+    assert isinstance(vl, int) and vl >= 0
+    assert isinstance(bitmask, int)
+    arg_dist = 1
+    while arg_dist < vl:
+        for i0 in range(0, vl, arg_dist * 2):
+            i1 = i0 + arg_dist
+            if remap is not None:
+                # FIXME(lkcl): does remap remap bitmask indexes like it does
+                # register indexes? This code assumes so.
+                i0 = remap[i0]
+                i1 = remap[i1]
+            if (bitmask >> i1) & 1:
+                if (bitmask >> i0) & 1:
+                    yield bin_op(i0, i0, i1)
+                else:
+                    yield Move(i0, i1)
+                bitmask |= 1 << i0
+        arg_dist *= 2
+
+
+if __name__ == "__main__":
+    for vl in range(0, 6):
+        for bitmask in range(2 ** vl):
+            print(f"vl={vl} bitmask={bin(bitmask)[2:].zfill(vl)}:")
+            program = list(tree_reduce(bitmask, vl))
+            for op in program:
+                print(f"    {op!s}")
+            # TODO: re-enable:
+            # print_tree(program)