Reimplement ir_function_inlining_visitor using ir_hierarchical_vistor

This commit is contained in:
Ian Romanick
2010-05-26 18:58:27 -07:00
parent 2fd22486d4
commit e668c2a9ee

View File

@@ -34,11 +34,11 @@
#include "ir_expression_flattening.h" #include "ir_expression_flattening.h"
#include "glsl_types.h" #include "glsl_types.h"
class ir_function_inlining_visitor : public ir_visitor { class ir_function_inlining_visitor : public ir_hierarchical_visitor {
public: public:
ir_function_inlining_visitor() ir_function_inlining_visitor()
{ {
/* empty */ progress = false;
} }
virtual ~ir_function_inlining_visitor() virtual ~ir_function_inlining_visitor()
@@ -46,30 +46,13 @@ public:
/* empty */ /* empty */
} }
/** virtual ir_visitor_status visit_enter(ir_expression *);
* \name Visit methods virtual ir_visitor_status visit_enter(ir_call *);
* virtual ir_visitor_status visit_enter(ir_assignment *);
* As typical for the visitor pattern, there must be one \c visit method for virtual ir_visitor_status visit_enter(ir_return *);
* each concrete subclass of \c ir_instruction. Virtual base classes within virtual ir_visitor_status visit_enter(ir_swizzle *);
* the hierarchy should not have \c visit methods.
*/ bool progress;
/*@{*/
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_variable *);
virtual void visit(ir_dereference_array *);
virtual void visit(ir_dereference_record *);
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 *);
/*@}*/
}; };
class variable_remap : public exec_node { class variable_remap : public exec_node {
@@ -336,39 +319,13 @@ automatic_inlining_predicate(ir_instruction *ir)
bool bool
do_function_inlining(exec_list *instructions) do_function_inlining(exec_list *instructions)
{ {
bool progress = false; ir_function_inlining_visitor v;
do_expression_flattening(instructions, automatic_inlining_predicate); do_expression_flattening(instructions, automatic_inlining_predicate);
foreach_iter(exec_list_iterator, iter, *instructions) { v.run(instructions);
ir_instruction *ir = (ir_instruction *)iter.get();
ir_assignment *assign = ir->as_assignment();
ir_call *call;
if (assign) { return v.progress;
call = assign->rhs->as_call();
if (!call || !can_inline(call))
continue;
/* generates the parameter setup, function body, and returns the return
* value of the function
*/
ir_rvalue *rhs = call->generate_inline(ir);
assert(rhs);
assign->rhs = rhs;
progress = true;
} else if ((call = ir->as_call()) && can_inline(call)) {
(void)call->generate_inline(ir);
ir->remove();
progress = true;
} else {
ir_function_inlining_visitor v;
ir->accept(&v);
}
}
return progress;
} }
ir_rvalue * ir_rvalue *
@@ -462,112 +419,59 @@ ir_call::generate_inline(ir_instruction *next_ir)
return NULL; return NULL;
} }
void
ir_function_inlining_visitor::visit(ir_variable *ir) ir_visitor_status
ir_function_inlining_visitor::visit_enter(ir_expression *ir)
{ {
(void) ir; (void) ir;
return visit_continue_with_parent;
} }
void ir_visitor_status
ir_function_inlining_visitor::visit(ir_loop *ir) ir_function_inlining_visitor::visit_enter(ir_return *ir)
{
do_function_inlining(&ir->body_instructions);
}
void
ir_function_inlining_visitor::visit(ir_loop_jump *ir)
{ {
(void) ir; (void) ir;
return visit_continue_with_parent;
} }
void ir_visitor_status
ir_function_inlining_visitor::visit(ir_function_signature *ir) ir_function_inlining_visitor::visit_enter(ir_swizzle *ir)
{ {
do_function_inlining(&ir->body); (void) ir;
return visit_continue_with_parent;
} }
void ir_visitor_status
ir_function_inlining_visitor::visit(ir_function *ir) ir_function_inlining_visitor::visit_enter(ir_call *ir)
{ {
foreach_iter(exec_list_iterator, iter, *ir) { if (can_inline(ir)) {
ir_function_signature *const sig = (ir_function_signature *) iter.get(); (void) ir->generate_inline(ir);
sig->accept(this); ir->remove();
this->progress = true;
} }
return visit_continue;
} }
void
ir_function_inlining_visitor::visit(ir_expression *ir) ir_visitor_status
ir_function_inlining_visitor::visit_enter(ir_assignment *ir)
{ {
unsigned int operand; ir_call *call = ir->rhs->as_call();
if (!call || !can_inline(call))
return visit_continue;
for (operand = 0; operand < ir->get_num_operands(); operand++) { /* generates the parameter setup, function body, and returns the return
ir->operands[operand]->accept(this); * value of the function
} */
} ir_rvalue *rhs = call->generate_inline(ir);
assert(rhs);
void ir->rhs = rhs;
ir_function_inlining_visitor::visit(ir_swizzle *ir) this->progress = true;
{
ir->val->accept(this); return visit_continue;
}
void
ir_function_inlining_visitor::visit(ir_dereference_variable *ir)
{
ir->var->accept(this);
}
void
ir_function_inlining_visitor::visit(ir_dereference_array *ir)
{
ir->array_index->accept(this);
ir->array->accept(this);
}
void
ir_function_inlining_visitor::visit(ir_dereference_record *ir)
{
ir->record->accept(this);
}
void
ir_function_inlining_visitor::visit(ir_assignment *ir)
{
ir->rhs->accept(this);
}
void
ir_function_inlining_visitor::visit(ir_constant *ir)
{
(void) ir;
}
void
ir_function_inlining_visitor::visit(ir_call *ir)
{
(void) ir;
}
void
ir_function_inlining_visitor::visit(ir_return *ir)
{
(void) ir;
}
void
ir_function_inlining_visitor::visit(ir_if *ir)
{
ir->condition->accept(this);
do_function_inlining(&ir->then_instructions);
do_function_inlining(&ir->else_instructions);
} }