X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglsl%2Fopt_tree_grafting.cpp;h=113abb7b043021f5d76aad34b6c6e5b500166304;hb=9add4e803877f97ad7f6d479d81d537426f09b6f;hp=9b569b8284f7cb696d715069ea6e4a2345d6c60f;hpb=32aaf89823de11e98cb59d5ec78c66cd3e74bcd4;p=mesa.git diff --git a/src/glsl/opt_tree_grafting.cpp b/src/glsl/opt_tree_grafting.cpp index 9b569b8284f..113abb7b043 100644 --- a/src/glsl/opt_tree_grafting.cpp +++ b/src/glsl/opt_tree_grafting.cpp @@ -22,7 +22,7 @@ */ /** - * \file ir_tree_grafting.cpp + * \file opt_tree_grafting.cpp * * Takes assignments to variables that are dereferenced only once and * pastes the RHS expression into where the variable is dereferenced. @@ -54,6 +54,8 @@ #include "ir_optimization.h" #include "glsl_types.h" +namespace { + static bool debug = false; class ir_tree_grafting_visitor : public ir_hierarchical_visitor { @@ -76,6 +78,8 @@ public: virtual ir_visitor_status visit_enter(class ir_swizzle *); virtual ir_visitor_status visit_enter(class ir_texture *); + ir_visitor_status check_graft(ir_instruction *ir, ir_variable *var); + bool do_graft(ir_rvalue **rvalue); bool progress; @@ -148,18 +152,17 @@ ir_tree_grafting_visitor::visit_enter(ir_loop *ir) return visit_stop; } +/** + * Check if we can continue grafting after writing to a variable. If the + * expression we're trying to graft references the variable, we must stop. + * + * \param ir An instruction that writes to a variable. + * \param var The variable being updated. + */ ir_visitor_status -ir_tree_grafting_visitor::visit_leave(ir_assignment *ir) +ir_tree_grafting_visitor::check_graft(ir_instruction *ir, ir_variable *var) { - if (do_graft(&ir->rhs) || - do_graft(&ir->condition)) - return visit_stop; - - /* If this assignment updates a variable used in the assignment - * we're trying to graft, then we're done. - */ - if (dereferences_variable(this->graft_assign->rhs, - ir->lhs->variable_referenced())) { + if (dereferences_variable(this->graft_assign->rhs, var)) { if (debug) { printf("graft killed by: "); ir->print(); @@ -171,6 +174,19 @@ ir_tree_grafting_visitor::visit_leave(ir_assignment *ir) return visit_continue; } +ir_visitor_status +ir_tree_grafting_visitor::visit_leave(ir_assignment *ir) +{ + if (do_graft(&ir->rhs) || + do_graft(&ir->condition)) + return visit_stop; + + /* If this assignment updates a variable used in the assignment + * we're trying to graft, then we're done. + */ + return check_graft(ir, ir->lhs->variable_referenced()); +} + ir_visitor_status ir_tree_grafting_visitor::visit_enter(ir_function *ir) { @@ -188,15 +204,19 @@ ir_tree_grafting_visitor::visit_enter(ir_function_signature *ir) ir_visitor_status ir_tree_grafting_visitor::visit_enter(ir_call *ir) { - exec_list_iterator sig_iter = ir->get_callee()->parameters.iterator(); + exec_list_iterator sig_iter = ir->callee->parameters.iterator(); /* Reminder: iterating ir_call iterates its parameters. */ foreach_iter(exec_list_iterator, iter, *ir) { ir_variable *sig_param = (ir_variable *)sig_iter.get(); ir_rvalue *ir = (ir_rvalue *)iter.get(); ir_rvalue *new_ir = ir; - if (sig_param->mode != ir_var_in) + if (sig_param->mode != ir_var_function_in + && sig_param->mode != ir_var_const_in) { + if (check_graft(ir, sig_param) == visit_stop) + return visit_stop; continue; + } if (do_graft(&new_ir)) { ir->replace_with(new_ir); @@ -205,6 +225,9 @@ ir_tree_grafting_visitor::visit_enter(ir_call *ir) sig_iter.next(); } + if (ir->return_deref && check_graft(ir, ir->return_deref->var) == visit_stop) + return visit_stop; + return visit_continue; } @@ -245,6 +268,7 @@ ir_tree_grafting_visitor::visit_enter(ir_texture *ir) { if (do_graft(&ir->coordinate) || do_graft(&ir->projector) || + do_graft(&ir->offset) || do_graft(&ir->shadow_comparitor)) return visit_stop; @@ -257,6 +281,7 @@ ir_tree_grafting_visitor::visit_enter(ir_texture *ir) break; case ir_txf: case ir_txl: + case ir_txs: if (do_graft(&ir->lod_info.lod)) return visit_stop; break; @@ -326,11 +351,12 @@ tree_grafting_basic_block(ir_instruction *bb_first, if (!lhs_var) continue; - if (lhs_var->mode == ir_var_out || - lhs_var->mode == ir_var_inout) + if (lhs_var->mode == ir_var_function_out || + lhs_var->mode == ir_var_function_inout || + lhs_var->mode == ir_var_shader_out) continue; - variable_entry *entry = info->refs->get_variable_entry(lhs_var); + ir_variable_refcount_entry *entry = info->refs->get_variable_entry(lhs_var); if (!entry->declaration || entry->assigned_count != 1 || @@ -347,6 +373,8 @@ tree_grafting_basic_block(ir_instruction *bb_first, } } +} /* unnamed namespace */ + /** * Does a copy propagation pass on the code present in the instruction stream. */