2 * Copyright © 2010 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
25 * \file opt_dead_functions.cpp
27 * Eliminates unused functions from the linked program.
31 #include "ir_visitor.h"
32 #include "ir_expression_flattening.h"
33 #include "glsl_types.h"
35 class signature_entry
: public exec_node
38 signature_entry(ir_function_signature
*sig
)
40 this->signature
= sig
;
44 ir_function_signature
*signature
;
48 class ir_dead_functions_visitor
: public ir_hierarchical_visitor
{
50 ir_dead_functions_visitor()
52 this->mem_ctx
= ralloc_context(NULL
);
53 this->seen_another_function_signature
= false;
56 ~ir_dead_functions_visitor()
58 ralloc_free(this->mem_ctx
);
61 virtual ir_visitor_status
visit_enter(ir_function_signature
*);
62 virtual ir_visitor_status
visit_enter(ir_call
*);
64 signature_entry
*get_signature_entry(ir_function_signature
*var
);
66 bool (*predicate
)(ir_instruction
*ir
);
68 bool seen_another_function_signature
;
70 /* List of signature_entry */
71 exec_list signature_list
;
77 ir_dead_functions_visitor::get_signature_entry(ir_function_signature
*sig
)
79 foreach_iter(exec_list_iterator
, iter
, this->signature_list
) {
80 signature_entry
*entry
= (signature_entry
*)iter
.get();
81 if (entry
->signature
== sig
)
85 signature_entry
*entry
= new(mem_ctx
) signature_entry(sig
);
86 this->signature_list
.push_tail(entry
);
92 ir_dead_functions_visitor::visit_enter(ir_function_signature
*ir
)
94 signature_entry
*entry
= this->get_signature_entry(ir
);
96 if (strcmp(ir
->function_name(), "main") == 0) {
100 /* If this is the first signature to look at, no need to descend to see
101 * if it has calls to another function signature.
103 if (!this->seen_another_function_signature
) {
104 this->seen_another_function_signature
= true;
105 return visit_continue_with_parent
;
108 return visit_continue
;
113 ir_dead_functions_visitor::visit_enter(ir_call
*ir
)
115 signature_entry
*entry
= this->get_signature_entry(ir
->get_callee());
119 return visit_continue
;
123 do_dead_functions(exec_list
*instructions
)
125 ir_dead_functions_visitor v
;
126 bool progress
= false;
128 visit_list_elements(&v
, instructions
);
130 /* Now that we've figured out which function signatures are used, remove
131 * the unused ones, and remove function definitions that have no more
134 foreach_iter(exec_list_iterator
, iter
, v
.signature_list
) {
135 signature_entry
*entry
= (signature_entry
*)iter
.get();
138 entry
->signature
->remove();
139 delete entry
->signature
;
145 /* We don't just do this above when we nuked a signature because of
148 foreach_iter(exec_list_iterator
, iter
, *instructions
) {
149 ir_instruction
*ir
= (ir_instruction
*)iter
.get();
150 ir_function
*func
= ir
->as_function();
152 if (func
&& func
->signatures
.is_empty()) {
153 /* At this point (post-linking), the symbol table is no
154 * longer in use, so not removing the function from the
155 * symbol table should be OK.