isaspec: De-duplicate bitset encoding

bitset encoding tends to have a lot of duplication, for ex. many
instructions with the same encoding modulo the fixed pattern.  Now that
encode_bitset is split out into it's own template, so that we can
capture the result, use a hash table to de-duplicate the bitset encoding
into "snippet" functions so that bitset cases with identical encoding
can re-use the same generated code.

Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13049>
This commit is contained in:
Rob Clark 2021-09-25 11:48:29 -07:00 committed by Marge Bot
parent 8726ed7221
commit 2b826582d8
2 changed files with 25 additions and 2 deletions

View File

@ -467,6 +467,21 @@ ${s.expr_name(leaf.get_root(), expr)}(struct encode_state *s, struct bitset_para
*/
%for root in s.encode_roots():
% for leaf in s.encode_leafs(root):
<% snippet = encode_bitset.render(s=s, root=root, leaf=leaf) %>
% if snippet not in root.snippets.keys():
<% snippet_name = "snippet" + root.get_c_name() + "_" + str(len(root.snippets)) %>
static bitmask_t
${snippet_name}(struct encode_state *s, struct bitset_params *p, ${root.encode.type} src)
{
bitmask_t val = uint64_t_to_bitmask(0);
${snippet}
return val;
}
<% root.snippets[snippet] = snippet_name %>
% endif
% endfor
static bitmask_t
encode${root.get_c_name()}(struct encode_state *s, struct bitset_params *p, ${root.encode.type} src)
{
@ -474,8 +489,10 @@ encode${root.get_c_name()}(struct encode_state *s, struct bitset_params *p, ${ro
switch (${root.get_c_name()}_case(s, src)) {
% for leaf in s.encode_leafs(root):
case ${s.case_name(root, leaf.name)}: {
<% snippet = encode_bitset.render(s=s, root=root, leaf=leaf) %>
bitmask_t val = uint64_t_to_bitmask(${hex(leaf.get_pattern().match)});
${encode_bitset.render(s=s, root=root, leaf=leaf)}
BITSET_OR(val.bitset, val.bitset, ${root.snippets[snippet]}(s, p, src).bitset);
return val;
}
% endfor
default:
@ -490,8 +507,10 @@ encode${root.get_c_name()}(struct encode_state *s, struct bitset_params *p, ${ro
return uint64_t_to_bitmask(0);
% else: # single case bitset, no switch
% for leaf in s.encode_leafs(root):
<% snippet = encode_bitset.render(s=s, root=root, leaf=leaf) %>
bitmask_t val = uint64_t_to_bitmask(${hex(leaf.get_pattern().match)});
${encode_bitset.render(s=s, root=root, leaf=leaf)}
BITSET_OR(val.bitset, val.bitset, ${root.snippets[snippet]}(s, p, src).bitset);
return val;
% endfor
% endif
}

View File

@ -248,6 +248,10 @@ class BitSet(object):
self.xml = xml
self.name = xml.attrib['name']
# Used for generated encoder, to de-duplicate encoding for
# similar instructions:
self.snippets = {}
if 'size' in xml.attrib:
assert('extends' not in xml.attrib)
self.size = int(xml.attrib['size'])