pan/bi: Add variable dest/src support to builder
authorAlyssa Rosenzweig <alyssa@collabora.com>
Fri, 22 Jul 2022 15:29:08 +0000 (11:29 -0400)
committerMarge Bot <emma+marge@anholt.net>
Fri, 2 Sep 2022 16:03:23 +0000 (16:03 +0000)
This will allow pseudo instructions to be allocated in a cleaner way when we
dynamically allocate their sources/destinationa.

Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17794>

src/panfrost/bifrost/bi_builder.h.py
src/panfrost/bifrost/bifrost_isa.py

index 931ade6..973b15d 100644 (file)
@@ -94,14 +94,25 @@ bi_instr * bi_${opcode.replace('.', '_').lower()}${to_suffix(ops[opcode])}(${sig
 {
     bi_instr *I = rzalloc(b->shader, bi_instr);
     I->op = BI_OPCODE_${opcode.replace('.', '_').upper()};
+
+% if ops[opcode]["variable_dests"]:
+    I->nr_dests = nr_dests;
+% else:
     I->nr_dests = ${ops[opcode]["dests"]};
-    I->nr_srcs = ${src_count(ops[opcode])};
 % for dest in range(ops[opcode]["dests"]):
     I->dest[${dest}] = dest${dest};
 % endfor
+%endif
+
+% if ops[opcode]["variable_srcs"]:
+    I->nr_srcs = nr_srcs;
+% else:
+    I->nr_srcs = ${src_count(ops[opcode])};
 % for src in range(src_count(ops[opcode])):
     I->src[${src}] = src${src};
 % endfor
+% endif
+
 % for mod in ops[opcode]["modifiers"]:
 % if not should_skip(mod, opcode):
     I->${mod} = ${mod};
@@ -120,7 +131,7 @@ bi_instr * bi_${opcode.replace('.', '_').lower()}${to_suffix(ops[opcode])}(${sig
     return I;
 }
 
-% if ops[opcode]["dests"] == 1:
+% if ops[opcode]["dests"] == 1 and not ops[opcode]["variable_dests"]:
 static inline
 bi_index bi_${opcode.replace('.', '_').lower()}(${signature(ops[opcode], modifiers, no_dests=True)})
 {
@@ -193,8 +204,10 @@ def signature(op, modifiers, typeful = False, sized = False, no_dests = False):
         ["bi_builder *b"] +
         (["nir_alu_type type"] if typeful == True else []) +
         (["unsigned bitsize"] if sized == True else []) +
-        ["bi_index dest{}".format(i) for i in range(0 if no_dests else op["dests"])] +
-        ["bi_index src{}".format(i) for i in range(src_count(op))] +
+        (["unsigned nr_dests"] if op["variable_dests"] else
+            ["bi_index dest{}".format(i) for i in range(0 if no_dests else op["dests"])]) +
+        (["unsigned nr_srcs"] if op["variable_srcs"] else
+            ["bi_index src{}".format(i) for i in range(src_count(op))]) +
         ["{} {}".format(
         "bool" if len(modifiers[T[0:-1]] if T[-1] in "0123" else modifiers[T]) == 2 else
         "enum bi_" + T[0:-1] if T[-1] in "0123" else
@@ -203,12 +216,18 @@ def signature(op, modifiers, typeful = False, sized = False, no_dests = False):
         ["uint32_t {}".format(imm) for imm in op["immediates"]])
 
 def arguments(op, temp_dest = True):
-    return ", ".join(
-        ["b"] +
-        ["bi_temp(b->shader)" if temp_dest else 'dest{}'.format(i) for i in range(op["dests"])] +
-        ["src{}".format(i) for i in range(src_count(op))] +
-        modifier_signature(op) +
-        op["immediates"])
+    dest_pattern = "bi_temp(b->shader)" if temp_dest else 'dest{}'
+    dests = [dest_pattern.format(i) for i in range(op["dests"])]
+    srcs = ["src{}".format(i) for i in range(src_count(op))]
+
+    # Variable source/destinations just pass in the count
+    if op["variable_dests"]:
+        dests = ["nr_dests"]
+
+    if op["variable_srcs"]:
+        srcs = ["nr_srcs"]
+
+    return ", ".join(["b"] + dests + srcs + modifier_signature(op) + op["immediates"])
 
 print(Template(COPYRIGHT + TEMPLATE).render(ops = ir_instructions, modifiers =
     modifier_lists, signature = signature, arguments = arguments, src_count =
index f262614..7152509 100644 (file)
@@ -132,6 +132,8 @@ def parse_instruction(ins, include_pseudo):
             'staging': ins.attrib.get('staging', '').split('=')[0],
             'staging_count': ins.attrib.get('staging', '=0').split('=')[1],
             'dests': int(ins.attrib.get('dests', '1')),
+            'variable_dests': ins.attrib.get('variable_dests', False),
+            'variable_srcs': ins.attrib.get('variable_srcs', False),
             'unused': ins.attrib.get('unused', False),
             'pseudo': ins.attrib.get('pseudo', False),
             'message': ins.attrib.get('message', 'none'),
@@ -243,6 +245,8 @@ def simplify_to_ir(ins):
             'staging': ins['staging'],
             'srcs': len(ins['srcs']),
             'dests': ins['dests'],
+            'variable_dests': ins['variable_dests'],
+            'variable_srcs': ins['variable_srcs'],
             'modifiers': [[m[0][0], m[2]] for m in ins['modifiers']],
             'immediates': [m[0] for m in ins['immediates']]
         }
@@ -281,6 +285,8 @@ def combine_ir_variants(instructions, key):
             'key': key,
             'srcs': variants[0]['srcs'],
             'dests': variants[0]['dests'],
+            'variable_dests': variants[0]['variable_dests'],
+            'variable_srcs': variants[0]['variable_srcs'],
             'staging': variants[0]['staging'],
             'immediates': sorted(variants[0]['immediates']),
             'modifiers': modifiers,