11591693c7b415e9869157c711fe11263c95d74eDavid Li /* 21591693c7b415e9869157c711fe11263c95d74eDavid Li * Copyright © 2010 Intel Corporation 31591693c7b415e9869157c711fe11263c95d74eDavid Li * 41591693c7b415e9869157c711fe11263c95d74eDavid Li * Permission is hereby granted, free of charge, to any person obtaining a 51591693c7b415e9869157c711fe11263c95d74eDavid Li * copy of this software and associated documentation files (the "Software"), 61591693c7b415e9869157c711fe11263c95d74eDavid Li * to deal in the Software without restriction, including without limitation 71591693c7b415e9869157c711fe11263c95d74eDavid Li * the rights to use, copy, modify, merge, publish, distribute, sublicense, 81591693c7b415e9869157c711fe11263c95d74eDavid Li * and/or sell copies of the Software, and to permit persons to whom the 91591693c7b415e9869157c711fe11263c95d74eDavid Li * Software is furnished to do so, subject to the following conditions: 101591693c7b415e9869157c711fe11263c95d74eDavid Li * 111591693c7b415e9869157c711fe11263c95d74eDavid Li * The above copyright notice and this permission notice (including the next 121591693c7b415e9869157c711fe11263c95d74eDavid Li * paragraph) shall be included in all copies or substantial portions of the 131591693c7b415e9869157c711fe11263c95d74eDavid Li * Software. 141591693c7b415e9869157c711fe11263c95d74eDavid Li * 151591693c7b415e9869157c711fe11263c95d74eDavid Li * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 161591693c7b415e9869157c711fe11263c95d74eDavid Li * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 171591693c7b415e9869157c711fe11263c95d74eDavid Li * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 181591693c7b415e9869157c711fe11263c95d74eDavid Li * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 191591693c7b415e9869157c711fe11263c95d74eDavid Li * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 201591693c7b415e9869157c711fe11263c95d74eDavid Li * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 211591693c7b415e9869157c711fe11263c95d74eDavid Li * DEALINGS IN THE SOFTWARE. 221591693c7b415e9869157c711fe11263c95d74eDavid Li */ 231591693c7b415e9869157c711fe11263c95d74eDavid Li 241591693c7b415e9869157c711fe11263c95d74eDavid Li /** 251591693c7b415e9869157c711fe11263c95d74eDavid Li * \file opt_dead_functions.cpp 261591693c7b415e9869157c711fe11263c95d74eDavid Li * 271591693c7b415e9869157c711fe11263c95d74eDavid Li * Eliminates unused functions from the linked program. 281591693c7b415e9869157c711fe11263c95d74eDavid Li */ 291591693c7b415e9869157c711fe11263c95d74eDavid Li 301591693c7b415e9869157c711fe11263c95d74eDavid Li #include "ir.h" 311591693c7b415e9869157c711fe11263c95d74eDavid Li #include "ir_visitor.h" 321591693c7b415e9869157c711fe11263c95d74eDavid Li #include "ir_expression_flattening.h" 331591693c7b415e9869157c711fe11263c95d74eDavid Li #include "glsl_types.h" 341591693c7b415e9869157c711fe11263c95d74eDavid Li 351591693c7b415e9869157c711fe11263c95d74eDavid Li class signature_entry : public exec_node 361591693c7b415e9869157c711fe11263c95d74eDavid Li { 371591693c7b415e9869157c711fe11263c95d74eDavid Li public: 381591693c7b415e9869157c711fe11263c95d74eDavid Li signature_entry(ir_function_signature *sig) 391591693c7b415e9869157c711fe11263c95d74eDavid Li { 401591693c7b415e9869157c711fe11263c95d74eDavid Li this->signature = sig; 411591693c7b415e9869157c711fe11263c95d74eDavid Li this->used = false; 421591693c7b415e9869157c711fe11263c95d74eDavid Li } 431591693c7b415e9869157c711fe11263c95d74eDavid Li 441591693c7b415e9869157c711fe11263c95d74eDavid Li ir_function_signature *signature; 451591693c7b415e9869157c711fe11263c95d74eDavid Li bool used; 461591693c7b415e9869157c711fe11263c95d74eDavid Li }; 471591693c7b415e9869157c711fe11263c95d74eDavid Li 481591693c7b415e9869157c711fe11263c95d74eDavid Li class ir_dead_functions_visitor : public ir_hierarchical_visitor { 491591693c7b415e9869157c711fe11263c95d74eDavid Li public: 501591693c7b415e9869157c711fe11263c95d74eDavid Li ir_dead_functions_visitor() 511591693c7b415e9869157c711fe11263c95d74eDavid Li { 52d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li this->mem_ctx = hieralloc_new(NULL); 531591693c7b415e9869157c711fe11263c95d74eDavid Li } 541591693c7b415e9869157c711fe11263c95d74eDavid Li 551591693c7b415e9869157c711fe11263c95d74eDavid Li ~ir_dead_functions_visitor() 561591693c7b415e9869157c711fe11263c95d74eDavid Li { 57d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li hieralloc_free(this->mem_ctx); 581591693c7b415e9869157c711fe11263c95d74eDavid Li } 591591693c7b415e9869157c711fe11263c95d74eDavid Li 601591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(ir_function_signature *); 611591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(ir_call *); 621591693c7b415e9869157c711fe11263c95d74eDavid Li 631591693c7b415e9869157c711fe11263c95d74eDavid Li signature_entry *get_signature_entry(ir_function_signature *var); 641591693c7b415e9869157c711fe11263c95d74eDavid Li 651591693c7b415e9869157c711fe11263c95d74eDavid Li bool (*predicate)(ir_instruction *ir); 661591693c7b415e9869157c711fe11263c95d74eDavid Li 671591693c7b415e9869157c711fe11263c95d74eDavid Li /* List of signature_entry */ 681591693c7b415e9869157c711fe11263c95d74eDavid Li exec_list signature_list; 691591693c7b415e9869157c711fe11263c95d74eDavid Li void *mem_ctx; 701591693c7b415e9869157c711fe11263c95d74eDavid Li }; 711591693c7b415e9869157c711fe11263c95d74eDavid Li 721591693c7b415e9869157c711fe11263c95d74eDavid Li 731591693c7b415e9869157c711fe11263c95d74eDavid Li signature_entry * 741591693c7b415e9869157c711fe11263c95d74eDavid Li ir_dead_functions_visitor::get_signature_entry(ir_function_signature *sig) 751591693c7b415e9869157c711fe11263c95d74eDavid Li { 761591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_iter(exec_list_iterator, iter, this->signature_list) { 771591693c7b415e9869157c711fe11263c95d74eDavid Li signature_entry *entry = (signature_entry *)iter.get(); 781591693c7b415e9869157c711fe11263c95d74eDavid Li if (entry->signature == sig) 791591693c7b415e9869157c711fe11263c95d74eDavid Li return entry; 801591693c7b415e9869157c711fe11263c95d74eDavid Li } 811591693c7b415e9869157c711fe11263c95d74eDavid Li 821591693c7b415e9869157c711fe11263c95d74eDavid Li signature_entry *entry = new(mem_ctx) signature_entry(sig); 831591693c7b415e9869157c711fe11263c95d74eDavid Li this->signature_list.push_tail(entry); 841591693c7b415e9869157c711fe11263c95d74eDavid Li return entry; 851591693c7b415e9869157c711fe11263c95d74eDavid Li } 861591693c7b415e9869157c711fe11263c95d74eDavid Li 871591693c7b415e9869157c711fe11263c95d74eDavid Li 881591693c7b415e9869157c711fe11263c95d74eDavid Li ir_visitor_status 891591693c7b415e9869157c711fe11263c95d74eDavid Li ir_dead_functions_visitor::visit_enter(ir_function_signature *ir) 901591693c7b415e9869157c711fe11263c95d74eDavid Li { 911591693c7b415e9869157c711fe11263c95d74eDavid Li signature_entry *entry = this->get_signature_entry(ir); 921591693c7b415e9869157c711fe11263c95d74eDavid Li 931591693c7b415e9869157c711fe11263c95d74eDavid Li if (strcmp(ir->function_name(), "main") == 0) { 941591693c7b415e9869157c711fe11263c95d74eDavid Li entry->used = true; 951591693c7b415e9869157c711fe11263c95d74eDavid Li } 961591693c7b415e9869157c711fe11263c95d74eDavid Li 971591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 981591693c7b415e9869157c711fe11263c95d74eDavid Li } 991591693c7b415e9869157c711fe11263c95d74eDavid Li 1001591693c7b415e9869157c711fe11263c95d74eDavid Li 1011591693c7b415e9869157c711fe11263c95d74eDavid Li ir_visitor_status 1021591693c7b415e9869157c711fe11263c95d74eDavid Li ir_dead_functions_visitor::visit_enter(ir_call *ir) 1031591693c7b415e9869157c711fe11263c95d74eDavid Li { 1041591693c7b415e9869157c711fe11263c95d74eDavid Li signature_entry *entry = this->get_signature_entry(ir->get_callee()); 1051591693c7b415e9869157c711fe11263c95d74eDavid Li 1061591693c7b415e9869157c711fe11263c95d74eDavid Li entry->used = true; 1071591693c7b415e9869157c711fe11263c95d74eDavid Li 1081591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 1091591693c7b415e9869157c711fe11263c95d74eDavid Li} 1101591693c7b415e9869157c711fe11263c95d74eDavid Li 1111591693c7b415e9869157c711fe11263c95d74eDavid Libool 1121591693c7b415e9869157c711fe11263c95d74eDavid Lido_dead_functions(exec_list *instructions) 1131591693c7b415e9869157c711fe11263c95d74eDavid Li{ 1141591693c7b415e9869157c711fe11263c95d74eDavid Li ir_dead_functions_visitor v; 1151591693c7b415e9869157c711fe11263c95d74eDavid Li bool progress = false; 1161591693c7b415e9869157c711fe11263c95d74eDavid Li 1171591693c7b415e9869157c711fe11263c95d74eDavid Li visit_list_elements(&v, instructions); 1181591693c7b415e9869157c711fe11263c95d74eDavid Li 1191591693c7b415e9869157c711fe11263c95d74eDavid Li /* Now that we've figured out which function signatures are used, remove 1201591693c7b415e9869157c711fe11263c95d74eDavid Li * the unused ones, and remove function definitions that have no more 1211591693c7b415e9869157c711fe11263c95d74eDavid Li * signatures. 1221591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1231591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_iter(exec_list_iterator, iter, v.signature_list) { 1241591693c7b415e9869157c711fe11263c95d74eDavid Li signature_entry *entry = (signature_entry *)iter.get(); 1251591693c7b415e9869157c711fe11263c95d74eDavid Li 1261591693c7b415e9869157c711fe11263c95d74eDavid Li if (!entry->used) { 1271591693c7b415e9869157c711fe11263c95d74eDavid Li entry->signature->remove(); 1281591693c7b415e9869157c711fe11263c95d74eDavid Li delete entry->signature; 1291591693c7b415e9869157c711fe11263c95d74eDavid Li progress = true; 1301591693c7b415e9869157c711fe11263c95d74eDavid Li } 1311591693c7b415e9869157c711fe11263c95d74eDavid Li delete(entry); 1321591693c7b415e9869157c711fe11263c95d74eDavid Li } 1331591693c7b415e9869157c711fe11263c95d74eDavid Li 1341591693c7b415e9869157c711fe11263c95d74eDavid Li /* We don't just do this above when we nuked a signature because of 1351591693c7b415e9869157c711fe11263c95d74eDavid Li * const pointers. 1361591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1371591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_iter(exec_list_iterator, iter, *instructions) { 1381591693c7b415e9869157c711fe11263c95d74eDavid Li ir_instruction *ir = (ir_instruction *)iter.get(); 1391591693c7b415e9869157c711fe11263c95d74eDavid Li ir_function *func = ir->as_function(); 1401591693c7b415e9869157c711fe11263c95d74eDavid Li 1411591693c7b415e9869157c711fe11263c95d74eDavid Li if (func && func->signatures.is_empty()) { 1421591693c7b415e9869157c711fe11263c95d74eDavid Li /* At this point (post-linking), the symbol table is no 1431591693c7b415e9869157c711fe11263c95d74eDavid Li * longer in use, so not removing the function from the 1441591693c7b415e9869157c711fe11263c95d74eDavid Li * symbol table should be OK. 1451591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1461591693c7b415e9869157c711fe11263c95d74eDavid Li func->remove(); 1471591693c7b415e9869157c711fe11263c95d74eDavid Li delete func; 1481591693c7b415e9869157c711fe11263c95d74eDavid Li progress = true; 1491591693c7b415e9869157c711fe11263c95d74eDavid Li } 1501591693c7b415e9869157c711fe11263c95d74eDavid Li } 1511591693c7b415e9869157c711fe11263c95d74eDavid Li 1521591693c7b415e9869157c711fe11263c95d74eDavid Li return progress; 1531591693c7b415e9869157c711fe11263c95d74eDavid Li} 154