From 29285882676388aacff123e8bdf025904abf8ea9 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 24 Jun 2010 15:32:15 -0700 Subject: glsl2: Move the compiler to the subdirectory it will live in in Mesa. --- src/glsl/glsl_symbol_table.h | 163 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 src/glsl/glsl_symbol_table.h (limited to 'src/glsl/glsl_symbol_table.h') diff --git a/src/glsl/glsl_symbol_table.h b/src/glsl/glsl_symbol_table.h new file mode 100644 index 0000000000..ae2fd3f4f1 --- /dev/null +++ b/src/glsl/glsl_symbol_table.h @@ -0,0 +1,163 @@ +/* -*- c++ -*- */ +/* + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#pragma once +#ifndef GLSL_SYMBOL_TABLE +#define GLSL_SYMBOL_TABLE + +#include + +#include "symbol_table.h" +#include "ir.h" +#include "glsl_types.h" + +/** + * Facade class for _mesa_symbol_table + * + * Wraps the existing \c _mesa_symbol_table data structure to enforce some + * type safe and some symbol table invariants. + */ +class glsl_symbol_table { +private: + enum glsl_symbol_name_space { + glsl_variable_name_space = 0, + glsl_type_name_space = 1, + glsl_function_name_space = 2 + }; + + static int + _glsl_symbol_table_destructor (glsl_symbol_table *table) + { + table->~glsl_symbol_table(); + + return 0; + } + +public: + /* Callers of this talloc-based new need not call delete. It's + * easier to just talloc_free 'ctx' (or any of its ancestors). */ + static void* operator new(size_t size, void *ctx) + { + void *table; + + table = talloc_size(ctx, size); + assert(table != NULL); + + talloc_set_destructor(table, (int (*)(void*)) _glsl_symbol_table_destructor); + + return table; + } + + /* If the user *does* call delete, that's OK, we will just + * talloc_free in that case. Here, C++ will have already called the + * destructor so tell talloc not to do that again. */ + static void operator delete(void *table) + { + talloc_set_destructor(table, NULL); + talloc_free(table); + } + + glsl_symbol_table() + { + table = _mesa_symbol_table_ctor(); + } + + ~glsl_symbol_table() + { + _mesa_symbol_table_dtor(table); + } + + void push_scope() + { + _mesa_symbol_table_push_scope(table); + } + + void pop_scope() + { + _mesa_symbol_table_pop_scope(table); + } + + /** + * Determine whether a name was declared at the current scope + */ + bool name_declared_this_scope(const char *name) + { + return _mesa_symbol_table_symbol_scope(table, -1, name) == 0; + } + + /** + * \name Methods to add symbols to the table + * + * There is some temptation to rename all these functions to \c add_symbol + * or similar. However, this breaks symmetry with the getter functions and + * reduces the clarity of the intention of code that uses these methods. + */ + /*@{*/ + bool add_variable(const char *name, ir_variable *v) + { + return _mesa_symbol_table_add_symbol(table, glsl_variable_name_space, + name, v) == 0; + } + + bool add_type(const char *name, const glsl_type *t) + { + return _mesa_symbol_table_add_symbol(table, glsl_type_name_space, + name, (void *) t) == 0; + } + + bool add_function(const char *name, ir_function *f) + { + return _mesa_symbol_table_add_symbol(table, glsl_function_name_space, + name, f) == 0; + } + /*@}*/ + + /** + * \name Methods to get symbols from the table + */ + /*@{*/ + ir_variable *get_variable(const char *name) + { + return (ir_variable *) + _mesa_symbol_table_find_symbol(table, glsl_variable_name_space, name); + } + + glsl_type *get_type(const char *name) + { + return (glsl_type *) + _mesa_symbol_table_find_symbol(table, glsl_type_name_space, name); + } + + ir_function *get_function(const char *name) + { + return (ir_function *) + _mesa_symbol_table_find_symbol(table, glsl_function_name_space, name); + } + /*@}*/ + +private: + struct _mesa_symbol_table *table; +}; + +#endif /* GLSL_SYMBOL_TABLE */ -- cgit v1.2.3 From 3d6012303c3ce24c75d209267e6914f706d025c5 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 24 Jun 2010 17:08:53 -0700 Subject: glsl2: Wrap includes of C interfaces with extern "C". --- src/glsl/ast_type.cpp | 2 ++ src/glsl/glsl_symbol_table.h | 2 ++ src/glsl/glsl_types.cpp | 3 ++- src/glsl/ir_clone.cpp | 2 ++ src/glsl/ir_function_inlining.cpp | 2 ++ src/glsl/ir_validate.cpp | 2 ++ src/glsl/linker.cpp | 2 ++ 7 files changed, 14 insertions(+), 1 deletion(-) (limited to 'src/glsl/glsl_symbol_table.h') diff --git a/src/glsl/ast_type.cpp b/src/glsl/ast_type.cpp index cb0852bb77..49dfde20e9 100644 --- a/src/glsl/ast_type.cpp +++ b/src/glsl/ast_type.cpp @@ -23,7 +23,9 @@ #include #include "ast.h" +extern "C" { #include "symbol_table.h" +} void ast_type_specifier::print(void) const diff --git a/src/glsl/glsl_symbol_table.h b/src/glsl/glsl_symbol_table.h index ae2fd3f4f1..8fbc66c974 100644 --- a/src/glsl/glsl_symbol_table.h +++ b/src/glsl/glsl_symbol_table.h @@ -28,7 +28,9 @@ #include +extern "C" { #include "symbol_table.h" +} #include "ir.h" #include "glsl_types.h" diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp index bef267fa6b..9a53fbdbcb 100644 --- a/src/glsl/glsl_types.cpp +++ b/src/glsl/glsl_types.cpp @@ -27,8 +27,9 @@ #include "glsl_parser_extras.h" #include "glsl_types.h" #include "builtin_types.h" +extern "C" { #include "hash_table.h" - +} hash_table *glsl_type::array_types = NULL; diff --git a/src/glsl/ir_clone.cpp b/src/glsl/ir_clone.cpp index 84176383fc..01a1ce3a6d 100644 --- a/src/glsl/ir_clone.cpp +++ b/src/glsl/ir_clone.cpp @@ -24,7 +24,9 @@ #include #include "ir.h" #include "glsl_types.h" +extern "C" { #include "hash_table.h" +} /** * Duplicate an IR variable diff --git a/src/glsl/ir_function_inlining.cpp b/src/glsl/ir_function_inlining.cpp index e55780c940..1adf67868e 100644 --- a/src/glsl/ir_function_inlining.cpp +++ b/src/glsl/ir_function_inlining.cpp @@ -33,7 +33,9 @@ #include "ir_function_inlining.h" #include "ir_expression_flattening.h" #include "glsl_types.h" +extern "C" { #include "hash_table.h" +} class ir_function_inlining_visitor : public ir_hierarchical_visitor { public: diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp index 507e88993f..1953852487 100644 --- a/src/glsl/ir_validate.cpp +++ b/src/glsl/ir_validate.cpp @@ -36,7 +36,9 @@ #include #include "ir.h" #include "ir_hierarchical_visitor.h" +extern "C" { #include "hash_table.h" +} static unsigned int hash_func(const void *key) { diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index ba382fe881..8547f74ce6 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -77,7 +77,9 @@ extern "C" { #include "ir.h" #include "ir_optimization.h" #include "program.h" +extern "C" { #include "hash_table.h" +} /** * Visitor that determines whether or not a variable is ever written. -- cgit v1.2.3 From 2e853ca23c8670246dd4efcee0706f68097652f7 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 5 Aug 2010 10:09:12 -0700 Subject: glsl2: Add a pass for removing unused functions. For a shader involving many small functions, this avoids running optimization across all of them after they've been inlined post-linking. Reduces the runtime of linking and running a fragment shader from Yo Frankie from 1.6 seconds to 0.9 seconds (-44.9%, +/- 3.3%). --- src/glsl/Makefile | 1 + src/glsl/glsl_symbol_table.h | 6 ++ src/glsl/ir.h | 1 - src/glsl/ir_dead_functions.cpp | 151 +++++++++++++++++++++++++++++++++++++++++ src/glsl/ir_optimization.h | 1 + src/glsl/linker.cpp | 1 + 6 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 src/glsl/ir_dead_functions.cpp (limited to 'src/glsl/glsl_symbol_table.h') diff --git a/src/glsl/Makefile b/src/glsl/Makefile index 3102947494..844385792a 100644 --- a/src/glsl/Makefile +++ b/src/glsl/Makefile @@ -39,6 +39,7 @@ CXX_SOURCES = \ ir.cpp \ ir_dead_code.cpp \ ir_dead_code_local.cpp \ + ir_dead_functions.cpp \ ir_div_to_mul_rcp.cpp \ ir_expression_flattening.cpp \ ir_function_can_inline.cpp \ diff --git a/src/glsl/glsl_symbol_table.h b/src/glsl/glsl_symbol_table.h index 27e825597c..02e4542cf3 100644 --- a/src/glsl/glsl_symbol_table.h +++ b/src/glsl/glsl_symbol_table.h @@ -133,6 +133,12 @@ public: return _mesa_symbol_table_add_symbol(table, glsl_function_name_space, name, f) == 0; } + + bool remove_function(const char *name, ir_function *f) + { + return _mesa_symbol_table_add_symbol(table, glsl_function_name_space, + name, f) == 0; + } /*@}*/ /** diff --git a/src/glsl/ir.h b/src/glsl/ir.h index e61485813d..f58602515e 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -410,7 +410,6 @@ public: */ const char *name; -private: /** * List of ir_function_signature for each overloaded function with this name. */ diff --git a/src/glsl/ir_dead_functions.cpp b/src/glsl/ir_dead_functions.cpp new file mode 100644 index 0000000000..26554441d3 --- /dev/null +++ b/src/glsl/ir_dead_functions.cpp @@ -0,0 +1,151 @@ + /* + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + + /** + * \file ir_dead_functions.cpp + * + * Eliminates unused functions from the linked program. + */ + + #include "ir.h" + #include "ir_visitor.h" + #include "ir_expression_flattening.h" + #include "glsl_types.h" + + class signature_entry : public exec_node + { + public: + signature_entry(ir_function_signature *sig) + { + this->signature = sig; + this->used = false; + } + + ir_function_signature *signature; + bool used; + }; + + class ir_dead_functions_visitor : public ir_hierarchical_visitor { + public: + ir_dead_functions_visitor() + { + this->mem_ctx = talloc_new(NULL); + } + + ~ir_dead_functions_visitor() + { + talloc_free(this->mem_ctx); + } + + virtual ir_visitor_status visit_enter(ir_function_signature *); + virtual ir_visitor_status visit_enter(ir_call *); + + signature_entry *get_signature_entry(ir_function_signature *var); + + bool (*predicate)(ir_instruction *ir); + + /* List of signature_entry */ + exec_list signature_list; + void *mem_ctx; + }; + + + signature_entry * + ir_dead_functions_visitor::get_signature_entry(ir_function_signature *sig) + { + foreach_iter(exec_list_iterator, iter, this->signature_list) { + signature_entry *entry = (signature_entry *)iter.get(); + if (entry->signature == sig) + return entry; + } + + signature_entry *entry = new(mem_ctx) signature_entry(sig); + this->signature_list.push_tail(entry); + return entry; + } + + + ir_visitor_status + ir_dead_functions_visitor::visit_enter(ir_function_signature *ir) + { + signature_entry *entry = this->get_signature_entry(ir); + + if (strcmp(ir->function_name(), "main") == 0) { + entry->used = true; + } + + return visit_continue; + } + + + ir_visitor_status + ir_dead_functions_visitor::visit_enter(ir_call *ir) + { + signature_entry *entry = this->get_signature_entry(ir->get_callee()); + + entry->used = true; + + return visit_continue; +} + +bool +do_dead_functions(exec_list *instructions) +{ + ir_dead_functions_visitor v; + bool progress = false; + + visit_list_elements(&v, instructions); + + /* Now that we've figured out which function signatures are used, remove + * the unused ones, and remove function definitions that have no more + * signatures. + */ + foreach_iter(exec_list_iterator, iter, v.signature_list) { + signature_entry *entry = (signature_entry *)iter.get(); + + if (!entry->used) { + entry->signature->remove(); + progress = true; + } + delete(entry); + } + + /* We don't just do this above when we nuked a signature because of + * const pointers. + */ + foreach_iter(exec_list_iterator, iter, *instructions) { + ir_instruction *ir = (ir_instruction *)iter.get(); + ir_function *func = ir->as_function(); + + if (func && func->signatures.is_empty()) { + /* At this point (post-linking), the symbol table is no + * longer in use, so not removing the function from the + * symbol table should be OK. + */ + func->remove(); + progress = true; + } + } + + return progress; +} diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h index 55ec327193..e0c0715cf5 100644 --- a/src/glsl/ir_optimization.h +++ b/src/glsl/ir_optimization.h @@ -36,6 +36,7 @@ bool do_copy_propagation(exec_list *instructions); bool do_dead_code(exec_list *instructions); bool do_dead_code_local(exec_list *instructions); bool do_dead_code_unlinked(exec_list *instructions); +bool do_dead_functions(exec_list *instructions); bool do_div_to_mul_rcp(exec_list *instructions); bool do_function_inlining(exec_list *instructions); bool do_if_return(exec_list *instructions); diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index 94db57d6a5..f9e24ca0f1 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -1286,6 +1286,7 @@ link_shaders(struct gl_shader_program *prog) progress = false; progress = do_function_inlining(ir) || progress; + progress = do_dead_functions(ir) || progress; progress = do_if_simplification(ir) || progress; progress = do_copy_propagation(ir) || progress; progress = do_dead_code_local(ir) || progress; -- cgit v1.2.3 From 1cbcf6693aa490c4dcb56712bfb9998deb270f08 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Sat, 14 Aug 2010 15:35:57 +0100 Subject: glsl: Standardize a few more uses of struct vs class keyword. --- src/glsl/glsl_symbol_table.h | 2 +- src/glsl/glsl_types.h | 13 +++++++------ src/glsl/ir.h | 4 ++-- src/glsl/ir_structure_splitting.cpp | 4 ++-- src/glsl/ir_tree_grafting.cpp | 2 +- 5 files changed, 13 insertions(+), 12 deletions(-) (limited to 'src/glsl/glsl_symbol_table.h') diff --git a/src/glsl/glsl_symbol_table.h b/src/glsl/glsl_symbol_table.h index 02e4542cf3..4cb7559e9a 100644 --- a/src/glsl/glsl_symbol_table.h +++ b/src/glsl/glsl_symbol_table.h @@ -40,7 +40,7 @@ extern "C" { * Wraps the existing \c _mesa_symbol_table data structure to enforce some * type safe and some symbol table invariants. */ -class glsl_symbol_table { +struct glsl_symbol_table { private: enum glsl_symbol_name_space { glsl_variable_name_space = 0, diff --git a/src/glsl/glsl_types.h b/src/glsl/glsl_types.h index 97d0d98c62..80cec635d9 100644 --- a/src/glsl/glsl_types.h +++ b/src/glsl/glsl_types.h @@ -35,6 +35,7 @@ extern "C" { } struct _mesa_glsl_parse_state; +struct glsl_symbol_table; extern "C" void _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state); @@ -209,7 +210,7 @@ struct glsl_type { /** * Generate the constructor for this type and add it to the symbol table */ - class ir_function *generate_constructor(class glsl_symbol_table *) const; + class ir_function *generate_constructor(glsl_symbol_table *) const; /** * Query the total number of scalars that make up a scalar, vector or matrix @@ -449,12 +450,12 @@ private: * the world in a public header file. */ /*@{*/ - static void generate_110_types(class glsl_symbol_table *); - static void generate_120_types(class glsl_symbol_table *); - static void generate_130_types(class glsl_symbol_table *); - static void generate_ARB_texture_rectangle_types(class glsl_symbol_table *, + static void generate_110_types(glsl_symbol_table *); + static void generate_120_types(glsl_symbol_table *); + static void generate_130_types(glsl_symbol_table *); + static void generate_ARB_texture_rectangle_types(glsl_symbol_table *, bool); - static void generate_EXT_texture_array_types(class glsl_symbol_table *, + static void generate_EXT_texture_array_types(glsl_symbol_table *, bool); /*@}*/ diff --git a/src/glsl/ir.h b/src/glsl/ir.h index eb9e6cdf0e..b04222893c 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -1383,11 +1383,11 @@ _mesa_glsl_release_functions(void); extern void reparent_ir(exec_list *list, void *mem_ctx); -class glsl_symbol_table; +struct glsl_symbol_table; extern void import_prototypes(const exec_list *source, exec_list *dest, - class glsl_symbol_table *symbols, void *mem_ctx); + struct glsl_symbol_table *symbols, void *mem_ctx); extern bool ir_has_call(ir_instruction *ir); diff --git a/src/glsl/ir_structure_splitting.cpp b/src/glsl/ir_structure_splitting.cpp index e257defb1a..c0244071ee 100644 --- a/src/glsl/ir_structure_splitting.cpp +++ b/src/glsl/ir_structure_splitting.cpp @@ -181,13 +181,13 @@ public: void split_deref(ir_dereference **deref); void handle_rvalue(ir_rvalue **rvalue); - struct variable_entry *get_splitting_entry(ir_variable *var); + variable_entry *get_splitting_entry(ir_variable *var); exec_list *variable_list; void *mem_ctx; }; -struct variable_entry * +variable_entry * ir_structure_splitting_visitor::get_splitting_entry(ir_variable *var) { assert(var); diff --git a/src/glsl/ir_tree_grafting.cpp b/src/glsl/ir_tree_grafting.cpp index e80db31cb3..6acc5b86c5 100644 --- a/src/glsl/ir_tree_grafting.cpp +++ b/src/glsl/ir_tree_grafting.cpp @@ -324,7 +324,7 @@ tree_grafting_basic_block(ir_instruction *bb_first, lhs_var->mode == ir_var_inout) continue; - struct variable_entry *entry = info->refs->get_variable_entry(lhs_var); + variable_entry *entry = info->refs->get_variable_entry(lhs_var); if (!entry->declaration || entry->assigned_count != 1 || -- cgit v1.2.3