16d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt/*
26d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * Copyright © 2010 Intel Corporation
36d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt *
46d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * Permission is hereby granted, free of charge, to any person obtaining a
56d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * copy of this software and associated documentation files (the "Software"),
66d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * to deal in the Software without restriction, including without limitation
76d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * the rights to use, copy, modify, merge, publish, distribute, sublicense,
86d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * and/or sell copies of the Software, and to permit persons to whom the
96d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * Software is furnished to do so, subject to the following conditions:
106d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt *
116d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * The above copyright notice and this permission notice (including the next
126d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * paragraph) shall be included in all copies or substantial portions of the
136d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * Software.
146d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt *
156d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
166d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
176d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
186d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
196d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
206d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
216d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * DEALINGS IN THE SOFTWARE.
226d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt */
236d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
246d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt/**
25df883eb1575a740bf91e01cbe2eaa4dbc1f9f154Chad Versace * \file lower_mat_op_to_vec.cpp
266d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt *
276d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * Breaks matrix operation expressions down to a series of vector operations.
286d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt *
296d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * Generally this is how we have to codegen matrix operations for a
306d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * GPU, so this gives us the chance to constant fold operations on a
316d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt * column or row.
326d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt */
336d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
346d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt#include "ir.h"
356d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt#include "ir_expression_flattening.h"
3624f984f64ae58c274f79eaf9148aea37df67131cEmil Velikov#include "compiler/glsl_types.h"
376d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
3810ef949424809d51c627008bb2feab5a067f8e08Eric Anholtnamespace {
3910ef949424809d51c627008bb2feab5a067f8e08Eric Anholt
406d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholtclass ir_mat_op_to_vec_visitor : public ir_hierarchical_visitor {
416d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholtpublic:
426d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   ir_mat_op_to_vec_visitor()
436d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   {
446d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt      this->made_progress = false;
453c96ef1f07f202312e1b7ae349b8bcbe7aed9e75Eric Anholt      this->mem_ctx = NULL;
466d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   }
476d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
486d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   ir_visitor_status visit_leave(ir_assignment *);
496d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
508fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt   ir_dereference *get_column(ir_dereference *val, int col);
518fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt   ir_rvalue *get_element(ir_dereference *val, int col, int row);
528fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt
538fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt   void do_mul_mat_mat(ir_dereference *result,
548fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt		       ir_dereference *a, ir_dereference *b);
558fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt   void do_mul_mat_vec(ir_dereference *result,
568fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt		       ir_dereference *a, ir_dereference *b);
578fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt   void do_mul_vec_mat(ir_dereference *result,
588fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt		       ir_dereference *a, ir_dereference *b);
598fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt   void do_mul_mat_scalar(ir_dereference *result,
608fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt			  ir_dereference *a, ir_dereference *b);
618fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt   void do_equal_mat_mat(ir_dereference *result, ir_dereference *a,
628fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt			 ir_dereference *b, bool test_equal);
636d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
643c96ef1f07f202312e1b7ae349b8bcbe7aed9e75Eric Anholt   void *mem_ctx;
656d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   bool made_progress;
666d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt};
676d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
6810ef949424809d51c627008bb2feab5a067f8e08Eric Anholt} /* anonymous namespace */
6910ef949424809d51c627008bb2feab5a067f8e08Eric Anholt
706d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholtstatic bool
716d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholtmat_op_to_vec_predicate(ir_instruction *ir)
726d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt{
736d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   ir_expression *expr = ir->as_expression();
746d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   unsigned int i;
756d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
766d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   if (!expr)
776d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt      return false;
786d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
796d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   for (i = 0; i < expr->get_num_operands(); i++) {
806d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt      if (expr->operands[i]->type->is_matrix())
816d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt	 return true;
826d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   }
836d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
846d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   return false;
856d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt}
866d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
876d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholtbool
886d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholtdo_mat_op_to_vec(exec_list *instructions)
896d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt{
906d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   ir_mat_op_to_vec_visitor v;
916d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
926d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   /* Pull out any matrix expression to a separate assignment to a
936d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt    * temp.  This will make our handling of the breakdown to
946d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt    * operations on the matrix's vector components much easier.
956d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt    */
966d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   do_expression_flattening(instructions, mat_op_to_vec_predicate);
976d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
986d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   visit_list_elements(&v, instructions);
996d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
1006d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   return v.made_progress;
1016d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt}
1026d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
1036d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholtir_rvalue *
1048fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholtir_mat_op_to_vec_visitor::get_element(ir_dereference *val, int col, int row)
10515ded6327966fa5824e34f7291e624994457f9b5Eric Anholt{
1068fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt   val = get_column(val, col);
10715ded6327966fa5824e34f7291e624994457f9b5Eric Anholt
1088fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt   return new(mem_ctx) ir_swizzle(val, row, 0, 0, 0, 1);
10915ded6327966fa5824e34f7291e624994457f9b5Eric Anholt}
11015ded6327966fa5824e34f7291e624994457f9b5Eric Anholt
11183cb310dbb47357c4b3065ca0d6739796d9e371fIan Romanickir_dereference *
1128fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholtir_mat_op_to_vec_visitor::get_column(ir_dereference *val, int row)
1136d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt{
1148fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt   val = val->clone(mem_ctx, NULL);
1158fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt
1168fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt   if (val->type->is_matrix()) {
1178fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt      val = new(mem_ctx) ir_dereference_array(val,
1188fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt					      new(mem_ctx) ir_constant(row));
1196d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   }
1206d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
1218fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt   return val;
1226d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt}
1236d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
12415ded6327966fa5824e34f7291e624994457f9b5Eric Anholtvoid
1258fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholtir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_dereference *result,
1268fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt					 ir_dereference *a,
1278fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt					 ir_dereference *b)
12815ded6327966fa5824e34f7291e624994457f9b5Eric Anholt{
129ab8c5347f18309c62a850dcbd14e505c99fc58e8Brian Paul   unsigned b_col, i;
13015ded6327966fa5824e34f7291e624994457f9b5Eric Anholt   ir_assignment *assign;
13115ded6327966fa5824e34f7291e624994457f9b5Eric Anholt   ir_expression *expr;
13215ded6327966fa5824e34f7291e624994457f9b5Eric Anholt
133408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt   for (b_col = 0; b_col < b->type->matrix_columns; b_col++) {
13415ded6327966fa5824e34f7291e624994457f9b5Eric Anholt      /* first column */
1353c96ef1f07f202312e1b7ae349b8bcbe7aed9e75Eric Anholt      expr = new(mem_ctx) ir_expression(ir_binop_mul,
136408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt					get_column(a, 0),
137408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt					get_element(b, b_col, 0));
13815ded6327966fa5824e34f7291e624994457f9b5Eric Anholt
13915ded6327966fa5824e34f7291e624994457f9b5Eric Anholt      /* following columns */
140408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt      for (i = 1; i < a->type->matrix_columns; i++) {
14115ded6327966fa5824e34f7291e624994457f9b5Eric Anholt	 ir_expression *mul_expr;
14215ded6327966fa5824e34f7291e624994457f9b5Eric Anholt
1433c96ef1f07f202312e1b7ae349b8bcbe7aed9e75Eric Anholt	 mul_expr = new(mem_ctx) ir_expression(ir_binop_mul,
144408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt					       get_column(a, i),
145408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt					       get_element(b, b_col, i));
1463c96ef1f07f202312e1b7ae349b8bcbe7aed9e75Eric Anholt	 expr = new(mem_ctx) ir_expression(ir_binop_add,
14715ded6327966fa5824e34f7291e624994457f9b5Eric Anholt					   expr,
14815ded6327966fa5824e34f7291e624994457f9b5Eric Anholt					   mul_expr);
14915ded6327966fa5824e34f7291e624994457f9b5Eric Anholt      }
15015ded6327966fa5824e34f7291e624994457f9b5Eric Anholt
1514f799e614264d2409fd32e3e3992405bb3fd924fEric Anholt      assign = new(mem_ctx) ir_assignment(get_column(result, b_col), expr);
15215ded6327966fa5824e34f7291e624994457f9b5Eric Anholt      base_ir->insert_before(assign);
15315ded6327966fa5824e34f7291e624994457f9b5Eric Anholt   }
15415ded6327966fa5824e34f7291e624994457f9b5Eric Anholt}
15515ded6327966fa5824e34f7291e624994457f9b5Eric Anholt
15615ded6327966fa5824e34f7291e624994457f9b5Eric Anholtvoid
1578fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholtir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_dereference *result,
1588fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt					 ir_dereference *a,
1598fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt					 ir_dereference *b)
16015ded6327966fa5824e34f7291e624994457f9b5Eric Anholt{
161ab8c5347f18309c62a850dcbd14e505c99fc58e8Brian Paul   unsigned i;
16215ded6327966fa5824e34f7291e624994457f9b5Eric Anholt   ir_assignment *assign;
16315ded6327966fa5824e34f7291e624994457f9b5Eric Anholt   ir_expression *expr;
16415ded6327966fa5824e34f7291e624994457f9b5Eric Anholt
16515ded6327966fa5824e34f7291e624994457f9b5Eric Anholt   /* first column */
1663c96ef1f07f202312e1b7ae349b8bcbe7aed9e75Eric Anholt   expr = new(mem_ctx) ir_expression(ir_binop_mul,
167408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt				     get_column(a, 0),
168408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt				     get_element(b, 0, 0));
16915ded6327966fa5824e34f7291e624994457f9b5Eric Anholt
17015ded6327966fa5824e34f7291e624994457f9b5Eric Anholt   /* following columns */
171408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt   for (i = 1; i < a->type->matrix_columns; i++) {
17215ded6327966fa5824e34f7291e624994457f9b5Eric Anholt      ir_expression *mul_expr;
17315ded6327966fa5824e34f7291e624994457f9b5Eric Anholt
1743c96ef1f07f202312e1b7ae349b8bcbe7aed9e75Eric Anholt      mul_expr = new(mem_ctx) ir_expression(ir_binop_mul,
175408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt					    get_column(a, i),
176408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt					    get_element(b, 0, i));
177e75b5954db52723a8590cd321b1998a079e9c1d4Eric Anholt      expr = new(mem_ctx) ir_expression(ir_binop_add, expr, mul_expr);
17815ded6327966fa5824e34f7291e624994457f9b5Eric Anholt   }
17915ded6327966fa5824e34f7291e624994457f9b5Eric Anholt
1808fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt   result = result->clone(mem_ctx, NULL);
1814f799e614264d2409fd32e3e3992405bb3fd924fEric Anholt   assign = new(mem_ctx) ir_assignment(result, expr);
18215ded6327966fa5824e34f7291e624994457f9b5Eric Anholt   base_ir->insert_before(assign);
18315ded6327966fa5824e34f7291e624994457f9b5Eric Anholt}
18415ded6327966fa5824e34f7291e624994457f9b5Eric Anholt
18515ded6327966fa5824e34f7291e624994457f9b5Eric Anholtvoid
1868fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholtir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_dereference *result,
1878fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt					 ir_dereference *a,
1888fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt					 ir_dereference *b)
18915ded6327966fa5824e34f7291e624994457f9b5Eric Anholt{
190ab8c5347f18309c62a850dcbd14e505c99fc58e8Brian Paul   unsigned i;
19115ded6327966fa5824e34f7291e624994457f9b5Eric Anholt
192408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt   for (i = 0; i < b->type->matrix_columns; i++) {
193408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt      ir_rvalue *column_result;
19415ded6327966fa5824e34f7291e624994457f9b5Eric Anholt      ir_expression *column_expr;
19515ded6327966fa5824e34f7291e624994457f9b5Eric Anholt      ir_assignment *column_assign;
19615ded6327966fa5824e34f7291e624994457f9b5Eric Anholt
1978fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt      column_result = result->clone(mem_ctx, NULL);
198408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt      column_result = new(mem_ctx) ir_swizzle(column_result, i, 0, 0, 0, 1);
19915ded6327966fa5824e34f7291e624994457f9b5Eric Anholt
2003c96ef1f07f202312e1b7ae349b8bcbe7aed9e75Eric Anholt      column_expr = new(mem_ctx) ir_expression(ir_binop_dot,
2018fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt					       a->clone(mem_ctx, NULL),
202408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt					       get_column(b, i));
20315ded6327966fa5824e34f7291e624994457f9b5Eric Anholt
204408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt      column_assign = new(mem_ctx) ir_assignment(column_result,
2054f799e614264d2409fd32e3e3992405bb3fd924fEric Anholt						 column_expr);
20615ded6327966fa5824e34f7291e624994457f9b5Eric Anholt      base_ir->insert_before(column_assign);
20715ded6327966fa5824e34f7291e624994457f9b5Eric Anholt   }
20815ded6327966fa5824e34f7291e624994457f9b5Eric Anholt}
20915ded6327966fa5824e34f7291e624994457f9b5Eric Anholt
21015ded6327966fa5824e34f7291e624994457f9b5Eric Anholtvoid
2118fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholtir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_dereference *result,
2128fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt					    ir_dereference *a,
2138fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt					    ir_dereference *b)
21415ded6327966fa5824e34f7291e624994457f9b5Eric Anholt{
215ab8c5347f18309c62a850dcbd14e505c99fc58e8Brian Paul   unsigned i;
21615ded6327966fa5824e34f7291e624994457f9b5Eric Anholt
217408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt   for (i = 0; i < a->type->matrix_columns; i++) {
21815ded6327966fa5824e34f7291e624994457f9b5Eric Anholt      ir_expression *column_expr;
21915ded6327966fa5824e34f7291e624994457f9b5Eric Anholt      ir_assignment *column_assign;
22015ded6327966fa5824e34f7291e624994457f9b5Eric Anholt
2213c96ef1f07f202312e1b7ae349b8bcbe7aed9e75Eric Anholt      column_expr = new(mem_ctx) ir_expression(ir_binop_mul,
222408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt					       get_column(a, i),
2238fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt					       b->clone(mem_ctx, NULL));
22415ded6327966fa5824e34f7291e624994457f9b5Eric Anholt
225408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt      column_assign = new(mem_ctx) ir_assignment(get_column(result, i),
2264f799e614264d2409fd32e3e3992405bb3fd924fEric Anholt						 column_expr);
22715ded6327966fa5824e34f7291e624994457f9b5Eric Anholt      base_ir->insert_before(column_assign);
22815ded6327966fa5824e34f7291e624994457f9b5Eric Anholt   }
22915ded6327966fa5824e34f7291e624994457f9b5Eric Anholt}
23015ded6327966fa5824e34f7291e624994457f9b5Eric Anholt
231120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanickvoid
2328fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholtir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_dereference *result,
2338fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt					   ir_dereference *a,
2348fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt					   ir_dereference *b,
235120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick					   bool test_equal)
236120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick{
237120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick   /* This essentially implements the following GLSL:
238120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick    *
239120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick    * bool equal(mat4 a, mat4 b)
240120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick    * {
241120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick    *   return !any(bvec4(a[0] != b[0],
242120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick    *                     a[1] != b[1],
243120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick    *                     a[2] != b[2],
244120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick    *                     a[3] != b[3]);
245120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick    * }
246120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick    *
247120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick    * bool nequal(mat4 a, mat4 b)
248120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick    * {
249120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick    *   return any(bvec4(a[0] != b[0],
250120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick    *                    a[1] != b[1],
251120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick    *                    a[2] != b[2],
252120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick    *                    a[3] != b[3]);
253120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick    * }
254120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick    */
255408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt   const unsigned columns = a->type->matrix_columns;
256120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick   const glsl_type *const bvec_type =
257120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick      glsl_type::get_instance(GLSL_TYPE_BOOL, columns, 1);
258120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick
259120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick   ir_variable *const tmp_bvec =
260120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick      new(this->mem_ctx) ir_variable(bvec_type, "mat_cmp_bvec",
261120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick				     ir_var_temporary);
262120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick   this->base_ir->insert_before(tmp_bvec);
263120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick
264120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick   for (unsigned i = 0; i < columns; i++) {
265120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick      ir_expression *const cmp =
266a47fd5c27de2b2d61776faa524f9b7ab1c915cdeEric Anholt	 new(this->mem_ctx) ir_expression(ir_binop_any_nequal,
267408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt					  get_column(a, i),
268408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt					  get_column(b, i));
269120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick
270120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick      ir_dereference *const lhs =
271120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick	 new(this->mem_ctx) ir_dereference_variable(tmp_bvec);
272120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick
273120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick      ir_assignment *const assign =
274b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt	 new(this->mem_ctx) ir_assignment(lhs, cmp, NULL, (1U << i));
275120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick
276120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick      this->base_ir->insert_before(assign);
277120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick   }
278120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick
279e75b5954db52723a8590cd321b1998a079e9c1d4Eric Anholt   ir_rvalue *const val = new(this->mem_ctx) ir_dereference_variable(tmp_bvec);
2802268a50ffde18f9907ee7321c8b503b52a23fb05Matt Turner   uint8_t vec_elems = val->type->vector_elements;
2812268a50ffde18f9907ee7321c8b503b52a23fb05Matt Turner   ir_expression *any =
2822268a50ffde18f9907ee7321c8b503b52a23fb05Matt Turner      new(this->mem_ctx) ir_expression(ir_binop_any_nequal, val,
2832268a50ffde18f9907ee7321c8b503b52a23fb05Matt Turner                                       new(this->mem_ctx) ir_constant(false,
2842268a50ffde18f9907ee7321c8b503b52a23fb05Matt Turner                                                                      vec_elems));
285120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick
286120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick   if (test_equal)
287e75b5954db52723a8590cd321b1998a079e9c1d4Eric Anholt      any = new(this->mem_ctx) ir_expression(ir_unop_logic_not, any);
288120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick
289120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick   ir_assignment *const assign =
2904f799e614264d2409fd32e3e3992405bb3fd924fEric Anholt      new(mem_ctx) ir_assignment(result->clone(mem_ctx, NULL), any);
291120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick   base_ir->insert_before(assign);
292120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick}
293120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick
294120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanickstatic bool
295120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanickhas_matrix_operand(const ir_expression *expr, unsigned &columns)
296120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick{
297120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick   for (unsigned i = 0; i < expr->get_num_operands(); i++) {
298120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick      if (expr->operands[i]->type->is_matrix()) {
299120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick	 columns = expr->operands[i]->type->matrix_columns;
300120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick	 return true;
301120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick      }
302120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick   }
303120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick
304120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick   return false;
305120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick}
306120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick
307120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick
3086d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholtir_visitor_status
309c7adb4ff1e7183d476680617d130b7dfed80d6c0Eric Anholtir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign)
3106d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt{
311c7adb4ff1e7183d476680617d130b7dfed80d6c0Eric Anholt   ir_expression *orig_expr = orig_assign->rhs->as_expression();
3126d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   unsigned int i, matrix_columns = 1;
3138fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt   ir_dereference *op[2];
3146d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
315c7adb4ff1e7183d476680617d130b7dfed80d6c0Eric Anholt   if (!orig_expr)
3166d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt      return visit_continue;
3176d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
318120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick   if (!has_matrix_operand(orig_expr, matrix_columns))
3196d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt      return visit_continue;
3206d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
321fc92e87b9757eda01caf0bb3e2c31b1dbbd73aa0Ian Romanick   assert(orig_expr->get_num_operands() <= 2);
322fc92e87b9757eda01caf0bb3e2c31b1dbbd73aa0Ian Romanick
323d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke   mem_ctx = ralloc_parent(orig_assign);
3243c96ef1f07f202312e1b7ae349b8bcbe7aed9e75Eric Anholt
3258fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt   ir_dereference_variable *result =
326c7adb4ff1e7183d476680617d130b7dfed80d6c0Eric Anholt      orig_assign->lhs->as_dereference_variable();
3278fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt   assert(result);
3286d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
3296d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   /* Store the expression operands in temps so we can use them
3306d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt    * multiple times.
3316d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt    */
332c7adb4ff1e7183d476680617d130b7dfed80d6c0Eric Anholt   for (i = 0; i < orig_expr->get_num_operands(); i++) {
3336d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt      ir_assignment *assign;
334487dd96c2706aa352ed44637507dd7f38ac80306Eric Anholt      ir_dereference *deref = orig_expr->operands[i]->as_dereference();
3356d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
336487dd96c2706aa352ed44637507dd7f38ac80306Eric Anholt      /* Avoid making a temporary if we don't need to to avoid aliasing. */
337487dd96c2706aa352ed44637507dd7f38ac80306Eric Anholt      if (deref &&
338487dd96c2706aa352ed44637507dd7f38ac80306Eric Anholt	  deref->variable_referenced() != result->variable_referenced()) {
339487dd96c2706aa352ed44637507dd7f38ac80306Eric Anholt	 op[i] = deref;
340487dd96c2706aa352ed44637507dd7f38ac80306Eric Anholt	 continue;
341487dd96c2706aa352ed44637507dd7f38ac80306Eric Anholt      }
342487dd96c2706aa352ed44637507dd7f38ac80306Eric Anholt
343487dd96c2706aa352ed44637507dd7f38ac80306Eric Anholt      /* Otherwise, store the operand in a temporary generally if it's
344487dd96c2706aa352ed44637507dd7f38ac80306Eric Anholt       * not a dereference.
345487dd96c2706aa352ed44637507dd7f38ac80306Eric Anholt       */
3468fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt      ir_variable *var = new(mem_ctx) ir_variable(orig_expr->operands[i]->type,
3478fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt						  "mat_op_to_vec",
3488fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt						  ir_var_temporary);
3498fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt      base_ir->insert_before(var);
3506d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
3518fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt      /* Note that we use this dereference for the assignment.  That means
3528fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt       * that others that want to use op[i] have to clone the deref.
3538fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt       */
3548fad8637ef42ccd064a4f90b090d8096ab968e58Eric Anholt      op[i] = new(mem_ctx) ir_dereference_variable(var);
3554f799e614264d2409fd32e3e3992405bb3fd924fEric Anholt      assign = new(mem_ctx) ir_assignment(op[i], orig_expr->operands[i]);
3566d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt      base_ir->insert_before(assign);
3576d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   }
3586d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
3596d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   /* OK, time to break down this matrix operation. */
360c7adb4ff1e7183d476680617d130b7dfed80d6c0Eric Anholt   switch (orig_expr->operation) {
36194f9ed701abe33b854f22577adffc4c7ad45cf18Dave Airlie   case ir_unop_d2f:
36294f9ed701abe33b854f22577adffc4c7ad45cf18Dave Airlie   case ir_unop_f2d:
363013bbbbb0ac52a12d1e4413700dc40dee70186f8Eric Anholt   case ir_unop_neg: {
364013bbbbb0ac52a12d1e4413700dc40dee70186f8Eric Anholt      /* Apply the operation to each column.*/
365013bbbbb0ac52a12d1e4413700dc40dee70186f8Eric Anholt      for (i = 0; i < matrix_columns; i++) {
366013bbbbb0ac52a12d1e4413700dc40dee70186f8Eric Anholt	 ir_expression *column_expr;
367013bbbbb0ac52a12d1e4413700dc40dee70186f8Eric Anholt	 ir_assignment *column_assign;
368013bbbbb0ac52a12d1e4413700dc40dee70186f8Eric Anholt
369a47fd5c27de2b2d61776faa524f9b7ab1c915cdeEric Anholt	 column_expr = new(mem_ctx) ir_expression(orig_expr->operation,
370408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt						  get_column(op[0], i));
371013bbbbb0ac52a12d1e4413700dc40dee70186f8Eric Anholt
372408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt	 column_assign = new(mem_ctx) ir_assignment(get_column(result, i),
3734f799e614264d2409fd32e3e3992405bb3fd924fEric Anholt						    column_expr);
374013bbbbb0ac52a12d1e4413700dc40dee70186f8Eric Anholt	 assert(column_assign->write_mask != 0);
375013bbbbb0ac52a12d1e4413700dc40dee70186f8Eric Anholt	 base_ir->insert_before(column_assign);
376013bbbbb0ac52a12d1e4413700dc40dee70186f8Eric Anholt      }
377013bbbbb0ac52a12d1e4413700dc40dee70186f8Eric Anholt      break;
378013bbbbb0ac52a12d1e4413700dc40dee70186f8Eric Anholt   }
3796d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   case ir_binop_add:
3806d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   case ir_binop_sub:
3816d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   case ir_binop_div:
38283cb310dbb47357c4b3065ca0d6739796d9e371fIan Romanick   case ir_binop_mod: {
3836d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt      /* For most operations, the matrix version is just going
3846d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt       * column-wise through and applying the operation to each column
3856d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt       * if available.
3866d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt       */
3876d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt      for (i = 0; i < matrix_columns; i++) {
3886d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt	 ir_expression *column_expr;
3896d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt	 ir_assignment *column_assign;
3906d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
391c7adb4ff1e7183d476680617d130b7dfed80d6c0Eric Anholt	 column_expr = new(mem_ctx) ir_expression(orig_expr->operation,
392408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt						  get_column(op[0], i),
393408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt						  get_column(op[1], i));
3946d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
395408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt	 column_assign = new(mem_ctx) ir_assignment(get_column(result, i),
3964f799e614264d2409fd32e3e3992405bb3fd924fEric Anholt						    column_expr);
39783cb310dbb47357c4b3065ca0d6739796d9e371fIan Romanick	 assert(column_assign->write_mask != 0);
3986d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt	 base_ir->insert_before(column_assign);
3996d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt      }
4006d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt      break;
40183cb310dbb47357c4b3065ca0d6739796d9e371fIan Romanick   }
4026d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   case ir_binop_mul:
403408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt      if (op[0]->type->is_matrix()) {
404408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt	 if (op[1]->type->is_matrix()) {
405408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt	    do_mul_mat_mat(result, op[0], op[1]);
406408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt	 } else if (op[1]->type->is_vector()) {
407408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt	    do_mul_mat_vec(result, op[0], op[1]);
40815ded6327966fa5824e34f7291e624994457f9b5Eric Anholt	 } else {
409408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt	    assert(op[1]->type->is_scalar());
410408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt	    do_mul_mat_scalar(result, op[0], op[1]);
41115ded6327966fa5824e34f7291e624994457f9b5Eric Anholt	 }
41215ded6327966fa5824e34f7291e624994457f9b5Eric Anholt      } else {
413408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt	 assert(op[1]->type->is_matrix());
414408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt	 if (op[0]->type->is_vector()) {
415408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt	    do_mul_vec_mat(result, op[0], op[1]);
41615ded6327966fa5824e34f7291e624994457f9b5Eric Anholt	 } else {
417408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt	    assert(op[0]->type->is_scalar());
418408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt	    do_mul_mat_scalar(result, op[1], op[0]);
41915ded6327966fa5824e34f7291e624994457f9b5Eric Anholt	 }
42015ded6327966fa5824e34f7291e624994457f9b5Eric Anholt      }
4216d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt      break;
422120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick
4234dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri   case ir_binop_all_equal:
4244dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri   case ir_binop_any_nequal:
425408377aed1dfae30605709fe1a134880a0386aa8Eric Anholt      do_equal_mat_mat(result, op[1], op[0],
4264dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri		       (orig_expr->operation == ir_binop_all_equal));
427120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick      break;
428120d5a95cb983b0b983089ba415486c55a9196e3Ian Romanick
4296d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   default:
430c7adb4ff1e7183d476680617d130b7dfed80d6c0Eric Anholt      printf("FINISHME: Handle matrix operation for %s\n",
431c6e8fd82ea118c66e69e4ad7967faec0715741aaIan Romanick	     ir_expression_operation_strings[orig_expr->operation]);
4326d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt      abort();
4336d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   }
434c7adb4ff1e7183d476680617d130b7dfed80d6c0Eric Anholt   orig_assign->remove();
4356d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   this->made_progress = true;
4366d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
4376d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt   return visit_continue;
4386d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt}
439