opt_constant_propagation.cpp revision 8bebbeb7c5b26ec9166a4644a2c051238d18509b
18bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt/*
28bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * Constantright © 2010 Intel Corporation
38bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt *
48bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * Permission is hereby granted, free of charge, to any person obtaining a
58bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * constant of this software and associated documentation files (the "Software"),
68bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * to deal in the Software without restriction, including without limitation
78bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * the rights to use, constant, modify, merge, publish, distribute, sublicense,
88bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * and/or sell copies of the Software, and to permit persons to whom the
98bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * Software is furnished to do so, subject to the following conditions:
108bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt *
118bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * The above constantright notice and this permission notice (including the next
128bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * paragraph) shall be included in all copies or substantial portions of the
138bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * Software.
148bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt *
158bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
168bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
178bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
188bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * THE AUTHORS OR CONSTANTRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
198bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
208bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
218bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * DEALINGS IN THE SOFTWARE.
228bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt */
238bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
248bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt/**
258bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * \file ir_constant_propagation.cpp
268bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt *
278bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * Tracks assignments of constants to channels of variables, and
288bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * usage of those constant channels with direct usage of the constants.
298bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt *
308bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * This can lead to constant folding and algebraic optimizations in
318bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * those later expressions, while causing no increase in instruction
328bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * count (due to constants being generally free to load from a
338bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * constant push buffer or as instruction immediate values) and
348bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * possibly reducing register pressure.
358bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt */
368bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
378bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt#include "ir.h"
388bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt#include "ir_visitor.h"
398bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt#include "ir_basic_block.h"
408bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt#include "ir_optimization.h"
418bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt#include "glsl_types.h"
428bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
438bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtclass acp_entry : public exec_node
448bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt{
458bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtpublic:
468bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   acp_entry(ir_variable *var, unsigned write_mask, ir_constant *constant)
478bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   {
488bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      assert(var);
498bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      assert(constant);
508bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      this->var = var;
518bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      this->write_mask = write_mask;
528bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      this->constant = constant;
538bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   }
548bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
558bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   ir_variable *var;
568bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   ir_constant *constant;
578bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   unsigned write_mask;
588bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt};
598bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
608bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
618bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtclass kill_entry : public exec_node
628bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt{
638bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtpublic:
648bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   kill_entry(ir_variable *var, unsigned write_mask)
658bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   {
668bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      assert(var);
678bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      this->var = var;
688bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      this->write_mask = write_mask;
698bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   }
708bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
718bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   ir_variable *var;
728bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   unsigned write_mask;
738bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt};
748bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
758bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtclass ir_constant_propagation_visitor : public ir_hierarchical_visitor {
768bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtpublic:
778bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   ir_constant_propagation_visitor()
788bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   {
798bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      progress = false;
808bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      mem_ctx = talloc_new(0);
818bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      this->acp = new(mem_ctx) exec_list;
828bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      this->kills = new(mem_ctx) exec_list;
838bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   }
848bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   ~ir_constant_propagation_visitor()
858bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   {
868bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      talloc_free(mem_ctx);
878bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   }
888bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
898bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   virtual ir_visitor_status visit_enter(class ir_loop *);
908bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   virtual ir_visitor_status visit_enter(class ir_function_signature *);
918bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   virtual ir_visitor_status visit_enter(class ir_function *);
928bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   virtual ir_visitor_status visit_enter(class ir_assignment *);
938bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   virtual ir_visitor_status visit_leave(class ir_assignment *);
948bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   virtual ir_visitor_status visit_enter(class ir_expression *);
958bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   virtual ir_visitor_status visit_enter(class ir_call *);
968bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   virtual ir_visitor_status visit_enter(class ir_if *);
978bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   virtual ir_visitor_status visit_enter(class ir_dereference_array *);
988bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   virtual ir_visitor_status visit_enter(class ir_texture *);
998bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
1008bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   void add_constant(ir_assignment *ir);
1018bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   void kill(ir_variable *ir, unsigned write_mask);
1028bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   void handle_if_block(exec_list *instructions);
1038bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   void handle_rvalue(ir_rvalue **rvalue);
1048bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
1058bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   /** List of acp_entry: The available constants to propagate */
1068bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   exec_list *acp;
1078bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
1088bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   /**
1098bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt    * List of kill_entry: The masks of variables whose values were
1108bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt    * killed in this block.
1118bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt    */
1128bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   exec_list *kills;
1138bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
1148bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   bool progress;
1158bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
1168bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   bool killed_all;
1178bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
1188bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   void *mem_ctx;
1198bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt};
1208bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
1218bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
1228bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtvoid
1238bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtir_constant_propagation_visitor::handle_rvalue(ir_rvalue **rvalue)
1248bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt{
1258bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   if (!*rvalue)
1268bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      return;
1278bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
1288bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   const glsl_type *type = (*rvalue)->type;
1298bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   if (!type->is_scalar() && !type->is_vector())
1308bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      return;
1318bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
1328bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   ir_swizzle *swiz = NULL;
1338bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   ir_dereference_variable *deref = (*rvalue)->as_dereference_variable();
1348bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   if (!deref) {
1358bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      swiz = (*rvalue)->as_swizzle();
1368bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      if (!swiz)
1378bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 return;
1388bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
1398bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      deref = swiz->val->as_dereference_variable();
1408bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      if (!deref)
1418bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 return;
1428bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   }
1438bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
1448bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   ir_constant_data data;
1458bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   memset(&data, 0, sizeof(data));
1468bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
1478bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   for (unsigned int i = 0; i < type->components(); i++) {
1488bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      int channel;
1498bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      acp_entry *found = NULL;
1508bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
1518bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      if (swiz) {
1528bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 switch (i) {
1538bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 case 0: channel = swiz->mask.x; break;
1548bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 case 1: channel = swiz->mask.y; break;
1558bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 case 2: channel = swiz->mask.z; break;
1568bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 case 3: channel = swiz->mask.w; break;
1578bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 default: assert(!"shouldn't be reached"); channel = 0; break;
1588bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 }
1598bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      } else {
1608bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 channel = i;
1618bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      }
1628bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
1638bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      foreach_iter(exec_list_iterator, iter, *this->acp) {
1648bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 acp_entry *entry = (acp_entry *)iter.get();
1658bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 if (entry->var == deref->var && entry->write_mask & (1 << channel)) {
1668bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	    found = entry;
1678bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	    break;
1688bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 }
1698bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      }
1708bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
1718bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      if (!found)
1728bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 return;
1738bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
1748bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      switch (type->base_type) {
1758bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      case GLSL_TYPE_FLOAT:
1768bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 data.f[i] = found->constant->value.f[channel];
1778bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 break;
1788bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      case GLSL_TYPE_INT:
1798bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 data.i[i] = found->constant->value.i[channel];
1808bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 break;
1818bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      case GLSL_TYPE_UINT:
1828bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 data.u[i] = found->constant->value.u[channel];
1838bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 break;
1848bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      case GLSL_TYPE_BOOL:
1858bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 data.b[i] = found->constant->value.b[channel];
1868bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 break;
1878bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      default:
1888bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 assert(!"not reached");
1898bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 break;
1908bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      }
1918bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   }
1928bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
1938bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   *rvalue = new(talloc_parent(deref)) ir_constant(type, &data);
1948bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   this->progress = true;
1958bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt}
1968bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
1978bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtir_visitor_status
1988bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtir_constant_propagation_visitor::visit_enter(ir_function_signature *ir)
1998bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt{
2008bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   /* Treat entry into a function signature as a completely separate
2018bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt    * block.  Any instructions at global scope will be shuffled into
2028bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt    * main() at link time, so they're irrelevant to us.
2038bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt    */
2048bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   exec_list *orig_acp = this->acp;
2058bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   exec_list *orig_kills = this->kills;
2068bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   bool orig_killed_all = this->killed_all;
2078bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
2088bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   this->acp = new(mem_ctx) exec_list;
2098bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   this->kills = new(mem_ctx) exec_list;
2108bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   this->killed_all = false;
2118bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
2128bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   visit_list_elements(this, &ir->body);
2138bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
2148bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   this->kills = orig_kills;
2158bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   this->acp = orig_acp;
2168bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   this->killed_all = orig_killed_all;
2178bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
2188bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   return visit_continue_with_parent;
2198bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt}
2208bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
2218bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtir_visitor_status
2228bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtir_constant_propagation_visitor::visit_enter(ir_assignment *ir)
2238bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt{
2248bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   handle_rvalue(&ir->condition);
2258bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   handle_rvalue(&ir->rhs);
2268bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
2278bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   return visit_continue;
2288bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt}
2298bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
2308bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtir_visitor_status
2318bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtir_constant_propagation_visitor::visit_leave(ir_assignment *ir)
2328bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt{
2338bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   kill(ir->lhs->variable_referenced(), ir->write_mask);
2348bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
2358bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   add_constant(ir);
2368bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
2378bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   return visit_continue;
2388bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt}
2398bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
2408bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtir_visitor_status
2418bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtir_constant_propagation_visitor::visit_enter(ir_expression *ir)
2428bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt{
2438bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   for (unsigned int i = 0; i < ir->get_num_operands(); i++) {
2448bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      handle_rvalue(&ir->operands[i]);
2458bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   }
2468bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
2478bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   return visit_continue;
2488bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt}
2498bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
2508bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtir_visitor_status
2518bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtir_constant_propagation_visitor::visit_enter(ir_function *ir)
2528bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt{
2538bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   (void) ir;
2548bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   return visit_continue;
2558bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt}
2568bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
2578bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtir_visitor_status
2588bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtir_constant_propagation_visitor::visit_enter(ir_call *ir)
2598bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt{
2608bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   /* Do constant propagation on call parameters, but skip any out params */
2618bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   exec_list_iterator sig_param_iter = ir->get_callee()->parameters.iterator();
2628bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   foreach_iter(exec_list_iterator, iter, ir->actual_parameters) {
2638bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      ir_variable *sig_param = (ir_variable *)sig_param_iter.get();
2648bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      ir_rvalue *param = (ir_rvalue *)iter.get();
2658bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      if (sig_param->mode != ir_var_out && sig_param->mode != ir_var_inout) {
2668bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 ir_rvalue *new_param = param;
2678bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 handle_rvalue(&new_param);
2688bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt         if (new_param != param)
2698bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	    param->replace_with(new_param);
2708bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 else
2718bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	    param->accept(this);
2728bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      }
2738bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      sig_param_iter.next();
2748bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   }
2758bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
2768bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   /* Since we're unlinked, we don't (necssarily) know the side effects of
2778bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt    * this call.  So kill all copies.
2788bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt    */
2798bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   acp->make_empty();
2808bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   this->killed_all = true;
2818bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
2828bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   return visit_continue_with_parent;
2838bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt}
2848bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
2858bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtvoid
2868bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtir_constant_propagation_visitor::handle_if_block(exec_list *instructions)
2878bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt{
2888bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   exec_list *orig_acp = this->acp;
2898bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   exec_list *orig_kills = this->kills;
2908bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   bool orig_killed_all = this->killed_all;
2918bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
2928bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   this->acp = new(mem_ctx) exec_list;
2938bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   this->kills = new(mem_ctx) exec_list;
2948bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   this->killed_all = false;
2958bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
2968bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   /* Populate the initial acp with a constant of the original */
2978bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   foreach_iter(exec_list_iterator, iter, *orig_acp) {
2988bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      acp_entry *a = (acp_entry *)iter.get();
2998bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      this->acp->push_tail(new(this->mem_ctx) acp_entry(a->var, a->write_mask,
3008bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt							a->constant));
3018bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   }
3028bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
3038bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   visit_list_elements(this, instructions);
3048bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
3058bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   if (this->killed_all) {
3068bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      orig_acp->make_empty();
3078bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   }
3088bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
3098bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   exec_list *new_kills = this->kills;
3108bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   this->kills = orig_kills;
3118bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   this->acp = orig_acp;
3128bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   this->killed_all = this->killed_all || orig_killed_all;
3138bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
3148bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   foreach_iter(exec_list_iterator, iter, *new_kills) {
3158bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      kill_entry *k = (kill_entry *)iter.get();
3168bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      kill(k->var, k->write_mask);
3178bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   }
3188bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt}
3198bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
3208bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtir_visitor_status
3218bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtir_constant_propagation_visitor::visit_enter(ir_if *ir)
3228bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt{
3238bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   ir->condition->accept(this);
3248bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   handle_rvalue(&ir->condition);
3258bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
3268bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   handle_if_block(&ir->then_instructions);
3278bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   handle_if_block(&ir->else_instructions);
3288bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
3298bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   /* handle_if_block() already descended into the children. */
3308bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   return visit_continue_with_parent;
3318bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt}
3328bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
3338bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtir_visitor_status
3348bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtir_constant_propagation_visitor::visit_enter(ir_dereference_array *ir)
3358bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt{
3368bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   handle_rvalue(&ir->array_index);
3378bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   return visit_continue;
3388bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt}
3398bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
3408bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtir_visitor_status
3418bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtir_constant_propagation_visitor::visit_enter(ir_texture *ir)
3428bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt{
3438bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   handle_rvalue(&ir->coordinate);
3448bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   handle_rvalue(&ir->projector);
3458bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   handle_rvalue(&ir->shadow_comparitor);
3468bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
3478bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   switch (ir->op) {
3488bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   case ir_tex:
3498bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      break;
3508bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   case ir_txb:
3518bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      handle_rvalue(&ir->lod_info.bias);
3528bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      break;
3538bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   case ir_txf:
3548bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   case ir_txl:
3558bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      handle_rvalue(&ir->lod_info.lod);
3568bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      break;
3578bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   case ir_txd:
3588bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      handle_rvalue(&ir->lod_info.grad.dPdx);
3598bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      handle_rvalue(&ir->lod_info.grad.dPdy);
3608bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      break;
3618bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   }
3628bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
3638bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   return visit_continue;
3648bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt}
3658bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
3668bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtir_visitor_status
3678bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtir_constant_propagation_visitor::visit_enter(ir_loop *ir)
3688bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt{
3698bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   exec_list *orig_acp = this->acp;
3708bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   exec_list *orig_kills = this->kills;
3718bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   bool orig_killed_all = this->killed_all;
3728bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
3738bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   /* FINISHME: For now, the initial acp for loops is totally empty.
3748bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt    * We could go through once, then go through again with the acp
3758bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt    * cloned minus the killed entries after the first run through.
3768bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt    */
3778bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   this->acp = new(mem_ctx) exec_list;
3788bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   this->kills = new(mem_ctx) exec_list;
3798bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   this->killed_all = false;
3808bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
3818bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   visit_list_elements(this, &ir->body_instructions);
3828bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
3838bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   if (this->killed_all) {
3848bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      orig_acp->make_empty();
3858bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   }
3868bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
3878bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   exec_list *new_kills = this->kills;
3888bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   this->kills = orig_kills;
3898bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   this->acp = orig_acp;
3908bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   this->killed_all = this->killed_all || orig_killed_all;
3918bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
3928bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   foreach_iter(exec_list_iterator, iter, *new_kills) {
3938bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      kill_entry *k = (kill_entry *)iter.get();
3948bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      kill(k->var, k->write_mask);
3958bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   }
3968bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
3978bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   /* already descended into the children. */
3988bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   return visit_continue_with_parent;
3998bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt}
4008bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
4018bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtvoid
4028bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtir_constant_propagation_visitor::kill(ir_variable *var, unsigned write_mask)
4038bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt{
4048bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   assert(var != NULL);
4058bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
4068bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   /* We don't track non-vectors. */
4078bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   if (!var->type->is_vector() && !var->type->is_scalar())
4088bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      return;
4098bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
4108bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   /* Remove any entries currently in the ACP for this kill. */
4118bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   foreach_iter(exec_list_iterator, iter, *this->acp) {
4128bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      acp_entry *entry = (acp_entry *)iter.get();
4138bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
4148bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      if (entry->var == var) {
4158bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 entry->write_mask &= ~write_mask;
4168bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 if (entry->write_mask == 0)
4178bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	    entry->remove();
4188bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      }
4198bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   }
4208bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
4218bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   /* Add this writemask of the variable to the list of killed
4228bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt    * variables in this block.
4238bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt    */
4248bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   foreach_iter(exec_list_iterator, iter, *this->kills) {
4258bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      kill_entry *entry = (kill_entry *)iter.get();
4268bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
4278bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      if (entry->var == var) {
4288bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 entry->write_mask |= write_mask;
4298bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 return;
4308bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      }
4318bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   }
4328bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   /* Not already in the list.  Make new entry. */
4338bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   this->kills->push_tail(new(this->mem_ctx) kill_entry(var, write_mask));
4348bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt}
4358bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
4368bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt/**
4378bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * Adds an entry to the available constant list if it's a plain assignment
4388bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * of a variable to a variable.
4398bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt */
4408bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtvoid
4418bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtir_constant_propagation_visitor::add_constant(ir_assignment *ir)
4428bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt{
4438bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   acp_entry *entry;
4448bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
4458bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   if (ir->condition) {
4468bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      ir_constant *condition = ir->condition->as_constant();
4478bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      if (!condition || !condition->value.b[0])
4488bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt	 return;
4498bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   }
4508bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
4518bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   if (!ir->write_mask)
4528bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      return;
4538bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
4548bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   ir_dereference_variable *deref = ir->lhs->as_dereference_variable();
4558bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   ir_constant *constant = ir->rhs->as_constant();
4568bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
4578bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   if (!deref || !constant)
4588bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      return;
4598bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
4608bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   /* Only do constant propagation on vectors.  Constant matrices,
4618bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt    * arrays, or structures would require more work elsewhere.
4628bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt    */
4638bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   if (!deref->var->type->is_vector() && !deref->var->type->is_scalar())
4648bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt      return;
4658bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
4668bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   entry = new(this->mem_ctx) acp_entry(deref->var, ir->write_mask, constant);
4678bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   this->acp->push_tail(entry);
4688bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt}
4698bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
4708bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt/**
4718bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt * Does a constant propagation pass on the code present in the instruction stream.
4728bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt */
4738bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtbool
4748bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholtdo_constant_propagation(exec_list *instructions)
4758bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt{
4768bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   ir_constant_propagation_visitor v;
4778bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
4788bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   visit_list_elements(&v, instructions);
4798bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt
4808bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt   return v.progress;
4818bebbeb7c5b26ec9166a4644a2c051238d18509bEric Anholt}
482