<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Mar 16, 2018 at 11:28 AM, Dylan Baker <span dir="ltr"><<a href="mailto:dylan@pnwbakers.com" target="_blank">dylan@pnwbakers.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Quoting Rob Clark (2018-03-15 18:43:28)<br><br><div><div class="h5">
> diff --git a/src/compiler/nir/nir_<wbr>intrinsics.py b/src/compiler/nir/nir_<wbr>intrinsics.py<br>
> new file mode 100644<br>
> index 00000000000..6bb6603586e<br>
> --- /dev/null<br>
> +++ b/src/compiler/nir/nir_<wbr>intrinsics.py<br>
> @@ -0,0 +1,547 @@<br>
> +#<br>
> +# Copyright (C) 2018 Red Hat<br>
> +# Copyright (C) 2014 Intel Corporation<br>
> +#<br>
> +# Permission is hereby granted, free of charge, to any person obtaining a<br>
> +# copy of this software and associated documentation files (the "Software"),<br>
> +# to deal in the Software without restriction, including without limitation<br>
> +# the rights to use, copy, modify, merge, publish, distribute, sublicense,<br>
> +# and/or sell copies of the Software, and to permit persons to whom the<br>
> +# Software is furnished to do so, subject to the following conditions:<br>
> +#<br>
> +# The above copyright notice and this permission notice (including the next<br>
> +# paragraph) shall be included in all copies or substantial portions of the<br>
> +# Software.<br>
> +#<br>
> +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br>
> +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br>
> +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL<br>
> +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br>
> +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING<br>
> +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS<br>
> +# IN THE SOFTWARE.<br>
> +#<br>
> +<br>
> +# This file defines all the available intrinsics in one place.<br>
> +#<br>
> +# The Intrinsic class corresponds one-to-one with nir_intrinsic_info<br>
> +# structure.<br>
> +<br>
> +class Intrinsic(object):<br>
> +   """Class that represents all the information about an intrinsic opcode.<br>
> +   NOTE: this must be kept in sync with nir_intrinsic_info.<br>
> +   """<br>
> +   def __init__(self, name, src_components, dest_components, num_variables,<br>
> +                indices, flags):<br>
> +       """Parameters:<br>
> +<br>
> +       - name: the intrinsic name<br>
> +       - src_components: list of the number of components per src, 0 means<br>
> +         vectorized instruction with number of components given in the<br>
> +         num_components field in nir_intrinsic_instr.<br>
> +       - dest_components: number of destination components, -1 means no<br>
> +         dest, 0 means number of components given in num_components field<br>
> +         in nir_intrinsic_instr.<br>
> +       - num_variables: the number of variables<br>
> +       - indices: list of constant indicies<br>
> +       - flags: list of semantic flags<br>
> +       """<br>
> +       assert isinstance(name, str)<br>
> +       assert isinstance(src_components, list)<br>
> +       if len(src_components) > 0:<br>
<br>
</div></div>if src_components:<br>
<span class=""><br>
> +           assert isinstance(src_components[0], int)<br>
> +       assert isinstance(dest_components, int)<br>
> +       assert isinstance(num_variables, int)<br>
> +       assert isinstance(indices, list)<br>
> +       if len(indices) > 0:<br>
<br>
</span>ditto<br>
<span class=""><br>
> +           assert isinstance(indices[0], str)<br>
> +       assert isinstance(flags, list)<br>
> +       if len(flags) > 0:<br>
<br>
</span>ditto<br>
<div><div class="h5"><br>
> +           assert isinstance(flags[0], str)<br>
> +<br>
> +       <a href="http://self.name" rel="noreferrer" target="_blank">self.name</a> = name<br>
> +       self.num_srcs = len(src_components)<br>
> +       self.src_components = src_components<br>
> +       self.has_dest = (dest_components >= 0)<br>
> +       self.dest_components = dest_components<br>
> +       self.num_variables = num_variables<br>
> +       self.num_indices = len(indices)<br>
> +       self.indices = indices<br>
> +       self.flags = flags<br>
> +<br>
> +#<br>
> +# Possible indices:<br>
> +#<br>
> +<br>
> +# A constant 'base' value that is added to an offset src:<br>
> +BASE = "NIR_INTRINSIC_BASE"<br>
> +# For store instructions, a writemask:<br>
> +WRMASK = "NIR_INTRINSIC_WRMASK"<br>
> +# The stream-id for GS emit_vertex/end_primitive intrinsics:<br>
> +STREAM_ID = "NIR_INTRINSIC_STREAM_ID"<br>
> +# The clip-plane id for load_user_clip_plane intrinsics:<br>
> +UCP_ID = "NIR_INTRINSIC_UCP_ID"<br>
> +# The amount of data, starting from BASE, that this instruction<br>
> +# may access.  This is used to provide bounds if the offset is<br>
> +# not constant.<br>
> +RANGE = "NIR_INTRINSIC_RANGE"<br>
> +# The vulkan descriptor set binding for vulkan_resource_index<br>
> +# intrinsic<br>
> +DESC_SET = "NIR_INTRINSIC_DESC_SET"<br>
> +# The vulkan descriptor set binding for vulkan_resource_index<br>
> +# intrinsic<br>
> +BINDING = "NIR_INTRINSIC_BINDING"<br>
> +# Component offset<br>
> +COMPONENT = "NIR_INTRINSIC_COMPONENT"<br>
> +# Interpolation mode (only meaningful for FS inputs)<br>
> +INTERP_MODE = "NIR_INTRINSIC_INTERP_MODE"<br>
> +# A binary nir_op to use when performing a reduction or scan operation<br>
> +REDUCTION_OP = "NIR_INTRINSIC_REDUCTION_OP"<br>
> +# Cluster size for reduction operations<br>
> +CLUSTER_SIZE = "NIR_INTRINSIC_CLUSTER_SIZE"<br>
> +<br>
> +#<br>
> +# Possible flags:<br>
> +#<br>
> +<br>
> +CAN_ELIMINATE = "NIR_INTRINSIC_CAN_ELIMINATE"<br>
> +CAN_REORDER   = "NIR_INTRINSIC_CAN_REORDER"<br>
> +<br>
> +intr_opcodes = {}<br>
> +<br>
> +def intrinsic(name, src_comp=[], dest_comp=-1, num_vars=0, indices=[], flags=[]):<br>
> +    assert name not in intr_opcodes<br>
> +    intr = Intrinsic(name, src_comp, dest_comp, num_vars, indices, flags)<br>
> +    intr_opcodes[name] = intr<br>
> +    return intr<br>
<br>
</div></div>Please either remove the return statement (since it's unused in so many cases),<br>
or, (and this is my preference), can we do something like:<br>
<br>
intr_opcodes = {<br>
    'nop': Intrinsic('nop', flags=[CAN_ELIMINATE]),<br>
    ...<br>
}<br>
<br>
I prefer this since each dictionary is clearly created without a function<br>
obscuring what's actually going on. If you dislike having to repeat the name you<br>
could even do something like:<br>
intr_opcodes = [<br>
    'nop': Intrinsic('nop', flags=[CAN_ELIMINATE]),<br>
    ...<br>
]<br>
intr_opcodes = {<a href="http://i.name" rel="noreferrer" target="_blank">i.name</a>: i for i in intr_opcodes}<br></blockquote><div><br></div><div>I'm not sure what I think about this.  On the one hand, having the dictionary explicitly declared is nice.  On the other hand, in nir_opcodes.py we have a bunch of other helper functions we declare along the way to help with specific kinds of opcodes.  It's not as practical to do this if everything is inside of a dictionary declaration.<br><br></div><div>--Jason<br></div></div></div></div>