diff options
author | Ian Romanick <ian.d.romanick@intel.com> | 2010-05-14 13:35:27 -0700 |
---|---|---|
committer | Ian Romanick <ian.d.romanick@intel.com> | 2010-05-17 12:03:13 -0700 |
commit | a0b4f3d631cefa6ee3f341461e4754ef6462f89b (patch) | |
tree | 88b7ddfe3912b0c245bcbef7c088baa8680e9222 | |
parent | 458d5c61ef9740cf589807c85d95e9ea4d04c03b (diff) |
Reimplement ir_if_simplicifation_visitor using ir_hierarchical_vistor
The output of all test cases was verified to be the same using diff.
-rw-r--r-- | ir_if_simplification.cpp | 210 |
1 files changed, 32 insertions, 178 deletions
diff --git a/ir_if_simplification.cpp b/ir_if_simplification.cpp index 1e6fd8d..042d0b6 100644 --- a/ir_if_simplification.cpp +++ b/ir_if_simplification.cpp @@ -30,202 +30,56 @@ #define NULL 0 #include "ir.h" -#include "ir_visitor.h" -#include "ir_function_inlining.h" -#include "glsl_types.h" -class ir_if_simplification_visitor : public ir_visitor { +class ir_if_simplification_visitor : public ir_hierarchical_visitor { public: ir_if_simplification_visitor() { - /* empty */ + this->made_progress = false; } - virtual ~ir_if_simplification_visitor() - { - /* empty */ - } + ir_visitor_status visit_leave(ir_if *); - /** - * \name Visit methods - * - * As typical for the visitor pattern, there must be one \c visit method for - * each concrete subclass of \c ir_instruction. Virtual base classes within - * the hierarchy should not have \c visit methods. - */ - /*@{*/ - virtual void visit(ir_variable *); - virtual void visit(ir_loop *); - virtual void visit(ir_loop_jump *); - virtual void visit(ir_function_signature *); - virtual void visit(ir_function *); - virtual void visit(ir_expression *); - virtual void visit(ir_swizzle *); - virtual void visit(ir_dereference *); - virtual void visit(ir_assignment *); - virtual void visit(ir_constant *); - virtual void visit(ir_call *); - virtual void visit(ir_return *); - virtual void visit(ir_if *); - /*@}*/ + bool made_progress; }; bool do_if_simplification(exec_list *instructions) { - bool progress = false; + ir_if_simplification_visitor v; - foreach_iter(exec_list_iterator, iter, *instructions) { - ir_instruction *ir = (ir_instruction *)iter.get(); - ir_if *conditional = ir->as_if(); + v.run(instructions); + return v.made_progress; +} - if (conditional) { - ir_constant *condition_constant; - condition_constant = - conditional->condition->constant_expression_value(); - if (condition_constant) { - /* Move the contents of the one branch of the conditional - * that matters out. - */ - if (condition_constant->value.b[0]) { - foreach_iter(exec_list_iterator, then_iter, - conditional->then_instructions) { - ir_instruction *then_ir = (ir_instruction *)then_iter.get(); - ir->insert_before(then_ir); - } - } else { - foreach_iter(exec_list_iterator, else_iter, - conditional->else_instructions) { - ir_instruction *else_ir = (ir_instruction *)else_iter.get(); - ir->insert_before(else_ir); - } - } - ir->remove(); - progress = true; - /* It would be nice to move the iterator back up to the point - * that we just spliced in contents. - */ - } else { - ir_if_simplification_visitor v; - ir->accept(&v); +ir_visitor_status +ir_if_simplification_visitor::visit_leave(ir_if *ir) +{ + /* FINISHME: Ideally there would be a way to note that the condition results + * FINISHME: in a constant before processing both of the other subtrees. + * FINISHME: This can probably be done with some flags, but it would take + * FINISHME: some work to get right. + */ + ir_constant *condition_constant = ir->condition->constant_expression_value(); + if (condition_constant) { + /* Move the contents of the one branch of the conditional + * that matters out. + */ + if (condition_constant->value.b[0]) { + foreach_iter(exec_list_iterator, then_iter, ir->then_instructions) { + ir_instruction *then_ir = (ir_instruction *)then_iter.get(); + ir->insert_before(then_ir); } } else { - ir_if_simplification_visitor v; - ir->accept(&v); + foreach_iter(exec_list_iterator, else_iter, ir->else_instructions) { + ir_instruction *else_ir = (ir_instruction *)else_iter.get(); + ir->insert_before(else_ir); + } } + ir->remove(); + this->made_progress = true; } - return progress; -} - -class variable_remap : public exec_node { -public: - variable_remap(const ir_variable *old_var, ir_variable *new_var) - : old_var(old_var), new_var(new_var) - { - /* empty */ - } - const ir_variable *old_var; - ir_variable *new_var; -}; - -void -ir_if_simplification_visitor::visit(ir_variable *ir) -{ - (void) ir; -} - - -void -ir_if_simplification_visitor::visit(ir_loop *ir) -{ - do_if_simplification(&ir->body_instructions); -} - -void -ir_if_simplification_visitor::visit(ir_loop_jump *ir) -{ - (void) ir; -} - - -void -ir_if_simplification_visitor::visit(ir_function_signature *ir) -{ - do_if_simplification(&ir->body); -} - - -void -ir_if_simplification_visitor::visit(ir_function *ir) -{ - foreach_iter(exec_list_iterator, iter, *ir) { - ir_function_signature *const sig = (ir_function_signature *) iter.get(); - sig->accept(this); - } -} - -void -ir_if_simplification_visitor::visit(ir_expression *ir) -{ - unsigned int operand; - - for (operand = 0; operand < ir->get_num_operands(); operand++) { - ir->operands[operand]->accept(this); - } -} - - -void -ir_if_simplification_visitor::visit(ir_swizzle *ir) -{ - ir->val->accept(this); -} - - -void -ir_if_simplification_visitor::visit(ir_dereference *ir) -{ - if (ir->mode == ir_dereference::ir_reference_array) { - ir->selector.array_index->accept(this); - } - ir->var->accept(this); -} - -void -ir_if_simplification_visitor::visit(ir_assignment *ir) -{ - ir->rhs->accept(this); -} - - -void -ir_if_simplification_visitor::visit(ir_constant *ir) -{ - (void) ir; -} - - -void -ir_if_simplification_visitor::visit(ir_call *ir) -{ - (void) ir; -} - - -void -ir_if_simplification_visitor::visit(ir_return *ir) -{ - (void) ir; -} - - -void -ir_if_simplification_visitor::visit(ir_if *ir) -{ - ir->condition->accept(this); - - do_if_simplification(&ir->then_instructions); - do_if_simplification(&ir->else_instructions); + return visit_continue; } |