[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