diff options
Diffstat (limited to 'src/glsl')
-rw-r--r-- | src/glsl/Makefile | 1 | ||||
-rw-r--r-- | src/glsl/ir.h | 6 | ||||
-rw-r--r-- | src/glsl/ir_import_prototypes.cpp | 137 |
3 files changed, 144 insertions, 0 deletions
diff --git a/src/glsl/Makefile b/src/glsl/Makefile index 2b040377b0c..47292bdb156 100644 --- a/src/glsl/Makefile +++ b/src/glsl/Makefile @@ -49,6 +49,7 @@ CXX_SOURCES = \ ir_if_return.cpp \ ir_if_simplification.cpp \ ir_if_to_cond_assign.cpp \ + ir_import_prototypes.cpp \ ir_mat_op_to_vec.cpp \ ir_mod_to_fract.cpp \ ir_print_visitor.cpp \ diff --git a/src/glsl/ir.h b/src/glsl/ir.h index e4b0e9f0822..38b10f5b06d 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -1318,4 +1318,10 @@ _mesa_glsl_initialize_functions(exec_list *instructions, extern void reparent_ir(exec_list *list, void *mem_ctx); +class glsl_symbol_table; + +extern void +import_prototypes(const exec_list *source, exec_list *dest, + class glsl_symbol_table *symbols, void *mem_ctx); + #endif /* IR_H */ diff --git a/src/glsl/ir_import_prototypes.cpp b/src/glsl/ir_import_prototypes.cpp new file mode 100644 index 00000000000..20aa8a6ae23 --- /dev/null +++ b/src/glsl/ir_import_prototypes.cpp @@ -0,0 +1,137 @@ +/* + * 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_import_prototypes.cpp + * Import function prototypes from one IR tree into another. + * + * \author Ian Romanick + */ +#include <cstdio> +#include "ir.h" +#include "glsl_symbol_table.h" + +/** + * Visitor used to import function prototypes + * + * Normally the \c clone method of either \c ir_function or + * \c ir_function_signature could be used. However, we don't want a complete + * clone of the \c ir_function_signature. We want everything \b except the + * body of the function. + */ +class import_prototype_visitor : public ir_hierarchical_visitor { +public: + /** + */ + import_prototype_visitor(exec_list *list, glsl_symbol_table *symbols, + void *mem_ctx) + { + this->mem_ctx = mem_ctx; + this->list = list; + this->symbols = symbols; + this->function = NULL; + } + + virtual ir_visitor_status visit_enter(ir_function *ir) + { + assert(this->function == NULL); + this->function = new(this->mem_ctx) ir_function(ir->name); + return visit_continue; + } + + virtual ir_visitor_status visit_leave(ir_function *ir) + { + (void) ir; + assert(this->function != NULL); + + /* Add the new function (and all its signatures) to the end of the + * instruction stream. + */ + list->push_tail(this->function); + + /* Add the new function to the symbol table. + */ + this->symbols->add_function(this->function->name, this->function); + + this->function = NULL; + return visit_continue; + } + + ir_visitor_status visit_enter(ir_function_signature *ir) + { + assert(this->function != NULL); + + ir_function_signature *copy = + new(mem_ctx) ir_function_signature(ir->return_type); + + copy->is_defined = false; + copy->is_built_in = ir->is_built_in; + + /* Clone the parameter list, but NOT the body. + */ + foreach_list_const(node, &ir->parameters) { + const ir_variable *const param = (const ir_variable *) node; + + assert(const_cast<ir_variable *>(param)->as_variable() != NULL); + + ir_variable *const param_copy = param->clone(NULL); + copy->parameters.push_tail(param_copy); + } + + this->function->add_signature(copy); + + /* Do not process child nodes of the ir_function_signature. There can + * never be any nodes inside the ir_function_signature that we care + * about. Instead continue with the next sibling. + */ + return visit_continue_with_parent; + } + +private: + exec_list *list; + ir_function *function; + glsl_symbol_table *symbols; + void *mem_ctx; +}; + + +/** + * Import function prototypes from one IR tree into another + * + * \param source Source instruction stream containing functions whose + * prototypes are to be imported + * \param dest Destination instruction stream where new \c ir_function and + * \c ir_function_signature nodes will be stored + * \param symbols Symbol table where new functions will be stored + * \param mem_ctx talloc memory context used for new allocations + */ +void +import_prototypes(const exec_list *source, exec_list *dest, + glsl_symbol_table *symbols, void *mem_ctx) +{ + import_prototype_visitor v(dest, symbols, mem_ctx); + + /* Making source be const is just extra documentation. + */ + v.run(const_cast<exec_list *>(source)); +} |