[Mesa-dev] [PATCH 1/5] glsl: Move the CSE equality functions to the ir class.

Jordan Justen jljusten at gmail.com
Thu Nov 14 20:16:22 PST 2013


I think you mentioned that you've merged Chris's d2573509 into this
already. With that change,
Reviewed-by: Jordan Justen <jordan.l.justen at intel.com>

On Thu, Nov 7, 2013 at 1:58 PM, Eric Anholt <eric at anholt.net> wrote:
> I want to reuse them in opt_algebraic.
> ---
>  src/glsl/Makefile.sources |   1 +
>  src/glsl/ir.h             |  22 ++++++
>  src/glsl/ir_equals.cpp    | 196 ++++++++++++++++++++++++++++++++++++++++++++++
>  src/glsl/opt_cse.cpp      | 178 +----------------------------------------
>  4 files changed, 220 insertions(+), 177 deletions(-)
>  create mode 100644 src/glsl/ir_equals.cpp
>
> diff --git a/src/glsl/Makefile.sources b/src/glsl/Makefile.sources
> index 2aabc05..43f122b 100644
> --- a/src/glsl/Makefile.sources
> +++ b/src/glsl/Makefile.sources
> @@ -33,6 +33,7 @@ LIBGLSL_FILES = \
>         $(GLSL_SRCDIR)/ir_clone.cpp \
>         $(GLSL_SRCDIR)/ir_constant_expression.cpp \
>         $(GLSL_SRCDIR)/ir.cpp \
> +       $(GLSL_SRCDIR)/ir_equals.cpp \
>         $(GLSL_SRCDIR)/ir_expression_flattening.cpp \
>         $(GLSL_SRCDIR)/ir_function_can_inline.cpp \
>         $(GLSL_SRCDIR)/ir_function_detect_recursion.cpp \
> diff --git a/src/glsl/ir.h b/src/glsl/ir.h
> index 2f06fb9..7859702 100644
> --- a/src/glsl/ir.h
> +++ b/src/glsl/ir.h
> @@ -139,6 +139,16 @@ public:
>     virtual class ir_jump *              as_jump()             { return NULL; }
>     /*@}*/
>
> +   /**
> +    * IR equality method: Return true if the referenced instruction would
> +    * return the same value as this one.
> +    *
> +    * This intended to be used for CSE and algebraic optimizations, on rvalues
> +    * in particular.  No support for other instruction types (assignments,
> +    * jumps, calls, etc.) is planned.
> +    */
> +   virtual bool equals(ir_instruction *ir);
> +
>  protected:
>     ir_instruction()
>     {
> @@ -1405,6 +1415,8 @@ public:
>        return this;
>     }
>
> +   virtual bool equals(ir_instruction *ir);
> +
>     virtual ir_expression *clone(void *mem_ctx, struct hash_table *ht) const;
>
>     /**
> @@ -1739,6 +1751,8 @@ public:
>
>     virtual ir_visitor_status accept(ir_hierarchical_visitor *);
>
> +   virtual bool equals(ir_instruction *ir);
> +
>     /**
>      * Return a string representing the ir_texture_opcode.
>      */
> @@ -1843,6 +1857,8 @@ public:
>
>     virtual ir_visitor_status accept(ir_hierarchical_visitor *);
>
> +   virtual bool equals(ir_instruction *ir);
> +
>     bool is_lvalue() const
>     {
>        return val->is_lvalue() && !mask.has_duplicates;
> @@ -1907,6 +1923,8 @@ public:
>        return this;
>     }
>
> +   virtual bool equals(ir_instruction *ir);
> +
>     /**
>      * Get the variable that is ultimately referenced by an r-value
>      */
> @@ -1965,6 +1983,8 @@ public:
>        return this;
>     }
>
> +   virtual bool equals(ir_instruction *ir);
> +
>     /**
>      * Get the variable that is ultimately referenced by an r-value
>      */
> @@ -2099,6 +2119,8 @@ public:
>
>     virtual ir_visitor_status accept(ir_hierarchical_visitor *);
>
> +   virtual bool equals(ir_instruction *ir);
> +
>     /**
>      * Get a particular component of a constant as a specific type
>      *
> diff --git a/src/glsl/ir_equals.cpp b/src/glsl/ir_equals.cpp
> new file mode 100644
> index 0000000..0b28b39
> --- /dev/null
> +++ b/src/glsl/ir_equals.cpp
> @@ -0,0 +1,196 @@
> +/*
> + * Copyright © 2013 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + */
> +
> +#include "ir.h"
> +
> +/**
> + * Helper for checking equality when one instruction might be NULL, since you
> + * can't a's vtable in that case.
> + */
> +static bool
> +possibly_null_equals(ir_instruction *a, ir_instruction *b)
> +{
> +   if (!a || !b)
> +      return !a && !b;
> +
> +   return a->equals(b);
> +}
> +
> +/**
> + * The base equality function: Return not equal for anything we don't know
> + * about.
> + */
> +bool
> +ir_instruction::equals(ir_instruction *ir)
> +{
> +   return false;
> +}
> +
> +bool
> +ir_constant::equals(ir_instruction *ir)
> +{
> +   const ir_constant *other = ir->as_constant();
> +   if (!other)
> +      return false;
> +
> +   if (type != other->type)
> +      return false;
> +
> +   for (unsigned i = 0; i < type->components(); i++) {
> +      if (value.u[i] != other->value.u[i])
> +         return false;
> +   }
> +
> +   return true;
> +}
> +
> +bool
> +ir_dereference_variable::equals(ir_instruction *ir)
> +{
> +   const ir_dereference_variable *other = ir->as_dereference_variable();
> +   if (!other)
> +      return false;
> +
> +   return var == other->var;
> +}
> +
> +bool
> +ir_dereference_array::equals(ir_instruction *ir)
> +{
> +   const ir_dereference_array *other = ir->as_dereference_array();
> +   if (!other)
> +      return false;
> +
> +   if (type != other->type)
> +      return false;
> +
> +   if (!array->equals(other->array))
> +      return false;
> +
> +   if (!array_index->equals(other->array_index))
> +      return false;
> +
> +   return true;
> +}
> +
> +bool
> +ir_swizzle::equals(ir_instruction *ir)
> +{
> +   const ir_swizzle *other = ir->as_swizzle();
> +   if (!other)
> +      return false;
> +
> +   if (type != other->type)
> +      return false;
> +
> +   if (mask.x != other->mask.x ||
> +       mask.y != other->mask.y ||
> +       mask.z != other->mask.z ||
> +       mask.w != other->mask.w) {
> +      return false;
> +   }
> +
> +   return val->equals(other->val);
> +}
> +
> +bool
> +ir_texture::equals(ir_instruction *ir)
> +{
> +   const ir_texture *other = ir->as_texture();
> +   if (!other)
> +      return false;
> +
> +   if (type != other->type)
> +      return false;
> +
> +   if (op != other->op)
> +      return false;
> +
> +   if (!possibly_null_equals(coordinate, other->coordinate))
> +      return false;
> +
> +   if (!possibly_null_equals(projector, other->projector))
> +      return false;
> +
> +   if (!possibly_null_equals(shadow_comparitor, other->shadow_comparitor))
> +      return false;
> +
> +   if (!possibly_null_equals(offset, other->offset))
> +      return false;
> +
> +   if (!sampler->equals(other->sampler))
> +      return false;
> +
> +   switch (op) {
> +   case ir_tex:
> +   case ir_lod:
> +   case ir_query_levels:
> +      break;
> +   case ir_txb:
> +      if (!lod_info.bias->equals(other->lod_info.bias))
> +         return false;
> +      break;
> +   case ir_txl:
> +   case ir_txf:
> +   case ir_txs:
> +      if (!lod_info.lod->equals(other->lod_info.lod))
> +         return false;
> +      break;
> +   case ir_txd:
> +      if (!lod_info.grad.dPdx->equals(other->lod_info.grad.dPdx) ||
> +          !lod_info.grad.dPdy->equals(other->lod_info.grad.dPdy))
> +         return false;
> +   case ir_txf_ms:
> +      if (!lod_info.sample_index->equals(other->lod_info.sample_index))
> +         return false;
> +      break;
> +   case ir_tg4:
> +      if (!lod_info.component->equals(other->lod_info.component))
> +         return false;
> +   default:
> +      assert(!"Unrecognized texture op");
> +   }
> +
> +   return true;
> +}
> +
> +bool
> +ir_expression::equals(ir_instruction *ir)
> +{
> +   const ir_expression *other = ir->as_expression();
> +   if (!other)
> +      return false;
> +
> +   if (type != other->type)
> +      return false;
> +
> +   if (operation != other->operation)
> +      return false;
> +
> +   for (unsigned i = 0; i < get_num_operands(); i++) {
> +      if (!operands[i]->equals(other->operands[i]))
> +         return false;
> +   }
> +
> +   return true;
> +}
> diff --git a/src/glsl/opt_cse.cpp b/src/glsl/opt_cse.cpp
> index c0fdb23..8f73940 100644
> --- a/src/glsl/opt_cse.cpp
> +++ b/src/glsl/opt_cse.cpp
> @@ -243,182 +243,6 @@ is_cse_candidate(ir_rvalue *ir)
>     return v.ok;
>  }
>
> -static bool
> -equals(ir_rvalue *a, ir_rvalue *b);
> -
> -static bool
> -equals(ir_constant *a, ir_constant *b)
> -{
> -   if (!a || !b)
> -      return false;
> -
> -   if (a->type != b->type)
> -      return false;
> -
> -   for (unsigned i = 0; i < a->type->components(); i++) {
> -      if (a->value.u[i] != b->value.u[i])
> -         return false;
> -   }
> -
> -   return true;
> -}
> -
> -static bool
> -equals(ir_dereference_variable *a, ir_dereference_variable *b)
> -{
> -   if (!a || !b)
> -      return false;
> -
> -   return a->var == b->var;
> -}
> -
> -static bool
> -equals(ir_dereference_array *a, ir_dereference_array *b)
> -{
> -   if (!a || !b)
> -      return false;
> -
> -   if (!equals(a->array, b->array))
> -      return false;
> -
> -   if (!equals(a->array_index, b->array_index))
> -      return false;
> -
> -   return true;
> -}
> -
> -static bool
> -equals(ir_swizzle *a, ir_swizzle *b)
> -{
> -   if (!a || !b)
> -      return false;
> -
> -   if (a->type != b->type)
> -      return false;
> -
> -   if (a->mask.x != b->mask.x ||
> -       a->mask.y != b->mask.y ||
> -       a->mask.z != b->mask.z ||
> -       a->mask.w != b->mask.w) {
> -      return false;
> -   }
> -
> -   return equals(a->val, b->val);
> -}
> -
> -static bool
> -equals(ir_texture *a, ir_texture *b)
> -{
> -   if (!a || !b)
> -      return false;
> -
> -   if (a->type != b->type)
> -      return false;
> -
> -   if (a->op != b->op)
> -      return false;
> -
> -   if (!equals(a->coordinate, b->coordinate))
> -      return false;
> -
> -   if (!equals(a->projector, b->projector))
> -      return false;
> -
> -   if (!equals(a->shadow_comparitor, b->shadow_comparitor))
> -      return false;
> -
> -   if (!equals(a->offset, b->offset))
> -      return false;
> -
> -   if (!equals(a->sampler, b->sampler))
> -      return false;
> -
> -   switch (a->op) {
> -   case ir_tex:
> -   case ir_lod:
> -   case ir_query_levels:
> -      break;
> -   case ir_txb:
> -      if (!equals(a->lod_info.bias, b->lod_info.bias))
> -         return false;
> -      break;
> -   case ir_txl:
> -   case ir_txf:
> -   case ir_txs:
> -      if (!equals(a->lod_info.lod, b->lod_info.lod))
> -         return false;
> -      break;
> -   case ir_txd:
> -      if (!equals(a->lod_info.grad.dPdx, b->lod_info.grad.dPdx) ||
> -          !equals(a->lod_info.grad.dPdy, b->lod_info.grad.dPdy))
> -         return false;
> -   case ir_txf_ms:
> -      if (!equals(a->lod_info.sample_index, b->lod_info.sample_index))
> -         return false;
> -      break;
> -   case ir_tg4:
> -      if (!equals(a->lod_info.component, b->lod_info.component))
> -         return false;
> -   default:
> -      assert(!"Unrecognized texture op");
> -   }
> -
> -   return true;
> -}
> -
> -static bool
> -equals(ir_expression *a, ir_expression *b)
> -{
> -   if (!a || !b)
> -      return false;
> -
> -   if (a->type != b->type)
> -      return false;
> -
> -   if (a->operation != b->operation)
> -      return false;
> -
> -   for (unsigned i = 0; i < a->get_num_operands(); i++) {
> -      if (!equals(a->operands[i], b->operands[i]))
> -         return false;
> -   }
> -
> -   return true;
> -}
> -
> -static bool
> -equals(ir_rvalue *a, ir_rvalue *b)
> -{
> -   if (!a || !b)
> -      return !a && !b;
> -
> -   if (a->type != b->type)
> -      return false;
> -
> -   switch (a->ir_type) {
> -   case ir_type_texture:
> -      return equals(a->as_texture(), b->as_texture());
> -
> -   case ir_type_constant:
> -      return equals(a->as_constant(), b->as_constant());
> -
> -   case ir_type_expression:
> -      return equals(a->as_expression(), b->as_expression());
> -
> -   case ir_type_dereference_variable:
> -      return equals(a->as_dereference_variable(), b->as_dereference_variable());
> -
> -   case ir_type_dereference_array:
> -      return equals(a->as_dereference_array(), b->as_dereference_array());
> -
> -   case ir_type_swizzle:
> -      return equals(a->as_swizzle(), b->as_swizzle());
> -
> -   default:
> -      return false;
> -   }
> -}
> -
>  /**
>   * Tries to find and return a reference to a previous computation of a given
>   * expression.
> @@ -439,7 +263,7 @@ cse_visitor::try_cse(ir_rvalue *rvalue)
>           printf("\n");
>        }
>
> -      if (!equals(rvalue, *entry->val))
> +      if (!rvalue->equals(*entry->val))
>           continue;
>
>        if (debug) {
> --
> 1.8.4.rc3
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list