162735694a1dfc09a16ea32312877cd49c7982118Eric Anholt/* 262735694a1dfc09a16ea32312877cd49c7982118Eric Anholt * Copyright © 2010 Intel Corporation 362735694a1dfc09a16ea32312877cd49c7982118Eric Anholt * 462735694a1dfc09a16ea32312877cd49c7982118Eric Anholt * Permission is hereby granted, free of charge, to any person obtaining a 562735694a1dfc09a16ea32312877cd49c7982118Eric Anholt * copy of this software and associated documentation files (the "Software"), 662735694a1dfc09a16ea32312877cd49c7982118Eric Anholt * to deal in the Software without restriction, including without limitation 762735694a1dfc09a16ea32312877cd49c7982118Eric Anholt * the rights to use, copy, modify, merge, publish, distribute, sublicense, 862735694a1dfc09a16ea32312877cd49c7982118Eric Anholt * and/or sell copies of the Software, and to permit persons to whom the 962735694a1dfc09a16ea32312877cd49c7982118Eric Anholt * Software is furnished to do so, subject to the following conditions: 1062735694a1dfc09a16ea32312877cd49c7982118Eric Anholt * 1162735694a1dfc09a16ea32312877cd49c7982118Eric Anholt * The above copyright notice and this permission notice (including the next 1262735694a1dfc09a16ea32312877cd49c7982118Eric Anholt * paragraph) shall be included in all copies or substantial portions of the 1362735694a1dfc09a16ea32312877cd49c7982118Eric Anholt * Software. 1462735694a1dfc09a16ea32312877cd49c7982118Eric Anholt * 1562735694a1dfc09a16ea32312877cd49c7982118Eric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1662735694a1dfc09a16ea32312877cd49c7982118Eric Anholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1762735694a1dfc09a16ea32312877cd49c7982118Eric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1862735694a1dfc09a16ea32312877cd49c7982118Eric Anholt * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1962735694a1dfc09a16ea32312877cd49c7982118Eric Anholt * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2062735694a1dfc09a16ea32312877cd49c7982118Eric Anholt * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2162735694a1dfc09a16ea32312877cd49c7982118Eric Anholt * DEALINGS IN THE SOFTWARE. 2262735694a1dfc09a16ea32312877cd49c7982118Eric Anholt */ 2362735694a1dfc09a16ea32312877cd49c7982118Eric Anholt 2462735694a1dfc09a16ea32312877cd49c7982118Eric Anholt/** 25df883eb1575a740bf91e01cbe2eaa4dbc1f9f154Chad Versace * \file opt_constant_folding.cpp 2662735694a1dfc09a16ea32312877cd49c7982118Eric Anholt * Replace constant-valued expressions with references to constant values. 2762735694a1dfc09a16ea32312877cd49c7982118Eric Anholt */ 2862735694a1dfc09a16ea32312877cd49c7982118Eric Anholt 2962735694a1dfc09a16ea32312877cd49c7982118Eric Anholt#include "ir.h" 3062735694a1dfc09a16ea32312877cd49c7982118Eric Anholt#include "ir_visitor.h" 316606fde3ec18288ecc4c6ce6d3fd32224a6c5248Eric Anholt#include "ir_rvalue_visitor.h" 32bdd9b1f3ffa2a195d983816adfeca20480256119Eric Anholt#include "ir_optimization.h" 3362735694a1dfc09a16ea32312877cd49c7982118Eric Anholt#include "glsl_types.h" 3462735694a1dfc09a16ea32312877cd49c7982118Eric Anholt 35337d9c955b070224f7278524af54ddacd8bb0f17Eric Anholtnamespace { 36337d9c955b070224f7278524af54ddacd8bb0f17Eric Anholt 3762735694a1dfc09a16ea32312877cd49c7982118Eric Anholt/** 3862735694a1dfc09a16ea32312877cd49c7982118Eric Anholt * Visitor class for replacing expressions with ir_constant values. 3962735694a1dfc09a16ea32312877cd49c7982118Eric Anholt */ 4062735694a1dfc09a16ea32312877cd49c7982118Eric Anholt 416606fde3ec18288ecc4c6ce6d3fd32224a6c5248Eric Anholtclass ir_constant_folding_visitor : public ir_rvalue_visitor { 42bdd9b1f3ffa2a195d983816adfeca20480256119Eric Anholtpublic: 43bdd9b1f3ffa2a195d983816adfeca20480256119Eric Anholt ir_constant_folding_visitor() 44bdd9b1f3ffa2a195d983816adfeca20480256119Eric Anholt { 456ecf62f673bf90d0969f8db032781b49a988975aEric Anholt this->progress = false; 46bdd9b1f3ffa2a195d983816adfeca20480256119Eric Anholt } 47bdd9b1f3ffa2a195d983816adfeca20480256119Eric Anholt 48bdd9b1f3ffa2a195d983816adfeca20480256119Eric Anholt virtual ~ir_constant_folding_visitor() 49bdd9b1f3ffa2a195d983816adfeca20480256119Eric Anholt { 50bdd9b1f3ffa2a195d983816adfeca20480256119Eric Anholt /* empty */ 51bdd9b1f3ffa2a195d983816adfeca20480256119Eric Anholt } 52bdd9b1f3ffa2a195d983816adfeca20480256119Eric Anholt 536606fde3ec18288ecc4c6ce6d3fd32224a6c5248Eric Anholt virtual ir_visitor_status visit_enter(ir_assignment *ir); 54428a3cd2d537a42c8a01765a5a53dca139e07443Eric Anholt virtual ir_visitor_status visit_enter(ir_call *ir); 553d23f0a90c982ad43a6f18ef69a23b2fcdb1d1d2Eric Anholt 566606fde3ec18288ecc4c6ce6d3fd32224a6c5248Eric Anholt virtual void handle_rvalue(ir_rvalue **rvalue); 576ecf62f673bf90d0969f8db032781b49a988975aEric Anholt 586ecf62f673bf90d0969f8db032781b49a988975aEric Anholt bool progress; 59bdd9b1f3ffa2a195d983816adfeca20480256119Eric Anholt}; 60bdd9b1f3ffa2a195d983816adfeca20480256119Eric Anholt 61337d9c955b070224f7278524af54ddacd8bb0f17Eric Anholt} /* unnamed namespace */ 62337d9c955b070224f7278524af54ddacd8bb0f17Eric Anholt 6362735694a1dfc09a16ea32312877cd49c7982118Eric Anholtvoid 646606fde3ec18288ecc4c6ce6d3fd32224a6c5248Eric Anholtir_constant_folding_visitor::handle_rvalue(ir_rvalue **rvalue) 653d23f0a90c982ad43a6f18ef69a23b2fcdb1d1d2Eric Anholt{ 668dbdcb0b43c8749018ff62dd5751190e54fe2445Eric Anholt if (*rvalue == NULL || (*rvalue)->ir_type == ir_type_constant) 673d23f0a90c982ad43a6f18ef69a23b2fcdb1d1d2Eric Anholt return; 683d23f0a90c982ad43a6f18ef69a23b2fcdb1d1d2Eric Anholt 692db7bb9c665d13fd067109b1171eedd92764791dEric Anholt /* Note that we do rvalue visitoring on leaving. So if an 702db7bb9c665d13fd067109b1171eedd92764791dEric Anholt * expression has a non-constant operand, no need to go looking 712db7bb9c665d13fd067109b1171eedd92764791dEric Anholt * down it to find if it's constant. This cuts the time of this 722db7bb9c665d13fd067109b1171eedd92764791dEric Anholt * pass down drastically. 732db7bb9c665d13fd067109b1171eedd92764791dEric Anholt */ 742db7bb9c665d13fd067109b1171eedd92764791dEric Anholt ir_expression *expr = (*rvalue)->as_expression(); 752db7bb9c665d13fd067109b1171eedd92764791dEric Anholt if (expr) { 762db7bb9c665d13fd067109b1171eedd92764791dEric Anholt for (unsigned int i = 0; i < expr->get_num_operands(); i++) { 772db7bb9c665d13fd067109b1171eedd92764791dEric Anholt if (!expr->operands[i]->as_constant()) 782db7bb9c665d13fd067109b1171eedd92764791dEric Anholt return; 792db7bb9c665d13fd067109b1171eedd92764791dEric Anholt } 802db7bb9c665d13fd067109b1171eedd92764791dEric Anholt } 812db7bb9c665d13fd067109b1171eedd92764791dEric Anholt 823d23f0a90c982ad43a6f18ef69a23b2fcdb1d1d2Eric Anholt ir_constant *constant = (*rvalue)->constant_expression_value(); 833d23f0a90c982ad43a6f18ef69a23b2fcdb1d1d2Eric Anholt if (constant) { 843d23f0a90c982ad43a6f18ef69a23b2fcdb1d1d2Eric Anholt *rvalue = constant; 856ecf62f673bf90d0969f8db032781b49a988975aEric Anholt this->progress = true; 863d23f0a90c982ad43a6f18ef69a23b2fcdb1d1d2Eric Anholt } else { 873d23f0a90c982ad43a6f18ef69a23b2fcdb1d1d2Eric Anholt (*rvalue)->accept(this); 883d23f0a90c982ad43a6f18ef69a23b2fcdb1d1d2Eric Anholt } 893d23f0a90c982ad43a6f18ef69a23b2fcdb1d1d2Eric Anholt} 903d23f0a90c982ad43a6f18ef69a23b2fcdb1d1d2Eric Anholt 916606fde3ec18288ecc4c6ce6d3fd32224a6c5248Eric Anholtir_visitor_status 926606fde3ec18288ecc4c6ce6d3fd32224a6c5248Eric Anholtir_constant_folding_visitor::visit_enter(ir_assignment *ir) 9362735694a1dfc09a16ea32312877cd49c7982118Eric Anholt{ 946606fde3ec18288ecc4c6ce6d3fd32224a6c5248Eric Anholt ir->rhs->accept(this); 956606fde3ec18288ecc4c6ce6d3fd32224a6c5248Eric Anholt handle_rvalue(&ir->rhs); 9614f8e16132409f38656e4874aa53bc471977f9adEric Anholt 9714f8e16132409f38656e4874aa53bc471977f9adEric Anholt if (ir->condition) { 986606fde3ec18288ecc4c6ce6d3fd32224a6c5248Eric Anholt ir->condition->accept(this); 996606fde3ec18288ecc4c6ce6d3fd32224a6c5248Eric Anholt handle_rvalue(&ir->condition); 1006606fde3ec18288ecc4c6ce6d3fd32224a6c5248Eric Anholt 1016606fde3ec18288ecc4c6ce6d3fd32224a6c5248Eric Anholt ir_constant *const_val = ir->condition->as_constant(); 10214f8e16132409f38656e4874aa53bc471977f9adEric Anholt /* If the condition is constant, either remove the condition or 10314f8e16132409f38656e4874aa53bc471977f9adEric Anholt * remove the never-executed assignment. 10414f8e16132409f38656e4874aa53bc471977f9adEric Anholt */ 10514f8e16132409f38656e4874aa53bc471977f9adEric Anholt if (const_val) { 10614f8e16132409f38656e4874aa53bc471977f9adEric Anholt if (const_val->value.b[0]) 10714f8e16132409f38656e4874aa53bc471977f9adEric Anholt ir->condition = NULL; 10814f8e16132409f38656e4874aa53bc471977f9adEric Anholt else 10914f8e16132409f38656e4874aa53bc471977f9adEric Anholt ir->remove(); 1108dbdcb0b43c8749018ff62dd5751190e54fe2445Eric Anholt this->progress = true; 11114f8e16132409f38656e4874aa53bc471977f9adEric Anholt } 11214f8e16132409f38656e4874aa53bc471977f9adEric Anholt } 11362735694a1dfc09a16ea32312877cd49c7982118Eric Anholt 1146606fde3ec18288ecc4c6ce6d3fd32224a6c5248Eric Anholt /* Don't descend into the LHS because we want it to stay as a 1156606fde3ec18288ecc4c6ce6d3fd32224a6c5248Eric Anholt * variable dereference. FINISHME: We probably should to get array 1166606fde3ec18288ecc4c6ce6d3fd32224a6c5248Eric Anholt * indices though. 1176606fde3ec18288ecc4c6ce6d3fd32224a6c5248Eric Anholt */ 1186606fde3ec18288ecc4c6ce6d3fd32224a6c5248Eric Anholt return visit_continue_with_parent; 119f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick} 120bdd9b1f3ffa2a195d983816adfeca20480256119Eric Anholt 121428a3cd2d537a42c8a01765a5a53dca139e07443Eric Anholtir_visitor_status 122428a3cd2d537a42c8a01765a5a53dca139e07443Eric Anholtir_constant_folding_visitor::visit_enter(ir_call *ir) 123428a3cd2d537a42c8a01765a5a53dca139e07443Eric Anholt{ 124d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke /* Attempt to constant fold parameters */ 12582065fa20ee3f2880a070f1f4f75509b910ceddeKenneth Graunke exec_list_iterator sig_iter = ir->callee->parameters.iterator(); 126428a3cd2d537a42c8a01765a5a53dca139e07443Eric Anholt foreach_iter(exec_list_iterator, iter, *ir) { 127428a3cd2d537a42c8a01765a5a53dca139e07443Eric Anholt ir_rvalue *param_rval = (ir_rvalue *)iter.get(); 128428a3cd2d537a42c8a01765a5a53dca139e07443Eric Anholt ir_variable *sig_param = (ir_variable *)sig_iter.get(); 129428a3cd2d537a42c8a01765a5a53dca139e07443Eric Anholt 130819d57fce94b20fa0d34da6f037f0a53c4a5bdc2Kenneth Graunke if (sig_param->mode == ir_var_in || sig_param->mode == ir_var_const_in) { 131428a3cd2d537a42c8a01765a5a53dca139e07443Eric Anholt ir_rvalue *new_param = param_rval; 132428a3cd2d537a42c8a01765a5a53dca139e07443Eric Anholt 133428a3cd2d537a42c8a01765a5a53dca139e07443Eric Anholt handle_rvalue(&new_param); 134428a3cd2d537a42c8a01765a5a53dca139e07443Eric Anholt if (new_param != param_rval) { 135428a3cd2d537a42c8a01765a5a53dca139e07443Eric Anholt param_rval->replace_with(new_param); 136428a3cd2d537a42c8a01765a5a53dca139e07443Eric Anholt } 137428a3cd2d537a42c8a01765a5a53dca139e07443Eric Anholt } 138ea709696185846c876581e1c41a21921826823ecEric Anholt sig_iter.next(); 139428a3cd2d537a42c8a01765a5a53dca139e07443Eric Anholt } 140428a3cd2d537a42c8a01765a5a53dca139e07443Eric Anholt 141d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke /* Next, see if the call can be replaced with an assignment of a constant */ 142d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke ir_constant *const_val = ir->constant_expression_value(); 143d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke 144d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke if (const_val != NULL) { 145d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke ir_assignment *assignment = 146d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke new(ralloc_parent(ir)) ir_assignment(ir->return_deref, const_val); 147d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke ir->replace_with(assignment); 148d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke } 149d884f60861f270cdcf7d9d47765efcf1e1de30b6Kenneth Graunke 150428a3cd2d537a42c8a01765a5a53dca139e07443Eric Anholt return visit_continue_with_parent; 151428a3cd2d537a42c8a01765a5a53dca139e07443Eric Anholt} 152428a3cd2d537a42c8a01765a5a53dca139e07443Eric Anholt 153bdd9b1f3ffa2a195d983816adfeca20480256119Eric Anholtbool 154bdd9b1f3ffa2a195d983816adfeca20480256119Eric Anholtdo_constant_folding(exec_list *instructions) 155bdd9b1f3ffa2a195d983816adfeca20480256119Eric Anholt{ 156bdd9b1f3ffa2a195d983816adfeca20480256119Eric Anholt ir_constant_folding_visitor constant_folding; 157bdd9b1f3ffa2a195d983816adfeca20480256119Eric Anholt 1586606fde3ec18288ecc4c6ce6d3fd32224a6c5248Eric Anholt visit_list_elements(&constant_folding, instructions); 159bdd9b1f3ffa2a195d983816adfeca20480256119Eric Anholt 1606ecf62f673bf90d0969f8db032781b49a988975aEric Anholt return constant_folding.progress; 161bdd9b1f3ffa2a195d983816adfeca20480256119Eric Anholt} 162