summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ast_to_hir.cpp7
-rw-r--r--ir.cpp33
-rw-r--r--ir_clone.cpp36
-rw-r--r--ir_function_inlining.cpp30
-rw-r--r--ir_hierarchical_visitor.cpp14
-rw-r--r--ir_hierarchical_visitor.h5
-rw-r--r--ir_print_visitor.cpp5
7 files changed, 88 insertions, 42 deletions
diff --git a/ast_to_hir.cpp b/ast_to_hir.cpp
index ddd4b73266..33eb27533f 100644
--- a/ast_to_hir.cpp
+++ b/ast_to_hir.cpp
@@ -523,12 +523,15 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
* ends up not being used, the temp will get copy-propagated out.
*/
ir_variable *var = new(ctx) ir_variable(rhs->type, "assignment_tmp");
- instructions->push_tail(new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var),
+ ir_dereference_variable *deref_var = new(ctx) ir_dereference_variable(var);
+ instructions->push_tail(var);
+ instructions->push_tail(new(ctx) ir_assignment(deref_var,
rhs,
NULL));
+ deref_var = new(ctx) ir_dereference_variable(var);
instructions->push_tail(new(ctx) ir_assignment(lhs,
- new(ctx) ir_dereference_variable(var),
+ deref_var,
NULL));
return new(ctx) ir_dereference_variable(var);
diff --git a/ir.cpp b/ir.cpp
index 6286d874e6..2756752ba4 100644
--- a/ir.cpp
+++ b/ir.cpp
@@ -297,39 +297,6 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list)
}
}
-ir_instruction *
-ir_constant::clone(struct hash_table *ht) const
-{
- void *ctx = talloc_parent(this);
-
- switch (this->type->base_type) {
- case GLSL_TYPE_UINT:
- case GLSL_TYPE_INT:
- case GLSL_TYPE_FLOAT:
- case GLSL_TYPE_BOOL:
- return new(ctx) ir_constant(this->type, &this->value);
-
- case GLSL_TYPE_STRUCT: {
- ir_constant *c = new(ctx)ir_constant;
-
- c->type = this->type;
- for (exec_node *node = this->components.head
- ; !node->is_tail_sentinal()
- ; node = node->next) {
- ir_constant *const orig = (ir_constant *) node;
-
- c->components.push_tail(orig->clone(NULL));
- }
-
- return c;
- }
-
- default:
- assert(!"Should not get here."); break;
- return NULL;
- }
-}
-
bool
ir_constant::get_bool_component(unsigned i) const
{
diff --git a/ir_clone.cpp b/ir_clone.cpp
index 5ffd3fc00b..84176383fc 100644
--- a/ir_clone.cpp
+++ b/ir_clone.cpp
@@ -47,7 +47,7 @@ ir_variable::clone(struct hash_table *ht) const
var->interpolation = this->interpolation;
if (ht) {
- hash_table_insert(ht, (void *)const_cast<ir_variable *>(this), var);
+ hash_table_insert(ht, var, (void *)const_cast<ir_variable *>(this));
}
return var;
@@ -251,3 +251,37 @@ ir_function_signature::clone(struct hash_table *ht) const
/* FINISHME */
abort();
}
+
+ir_instruction *
+ir_constant::clone(struct hash_table *ht) const
+{
+ void *ctx = talloc_parent(this);
+ (void)ht;
+
+ switch (this->type->base_type) {
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ case GLSL_TYPE_FLOAT:
+ case GLSL_TYPE_BOOL:
+ return new(ctx) ir_constant(this->type, &this->value);
+
+ case GLSL_TYPE_STRUCT: {
+ ir_constant *c = new(ctx) ir_constant;
+
+ c->type = this->type;
+ for (exec_node *node = this->components.head
+ ; !node->is_tail_sentinal()
+ ; node = node->next) {
+ ir_constant *const orig = (ir_constant *) node;
+
+ c->components.push_tail(orig->clone(NULL));
+ }
+
+ return c;
+ }
+
+ default:
+ assert(!"Should not get here."); break;
+ return NULL;
+ }
+}
diff --git a/ir_function_inlining.cpp b/ir_function_inlining.cpp
index 8a1cf4f1d2..e55780c940 100644
--- a/ir_function_inlining.cpp
+++ b/ir_function_inlining.cpp
@@ -91,6 +91,27 @@ do_function_inlining(exec_list *instructions)
return v.progress;
}
+static void
+replace_return_with_assignment(ir_instruction *ir, void *data)
+{
+ void *ctx = talloc_parent(ir);
+ ir_variable *retval = (ir_variable *)data;
+ ir_return *ret = ir->as_return();
+
+ if (ret) {
+ if (ret->value) {
+ ir_rvalue *lhs = new(ctx) ir_dereference_variable(retval);
+ ret->insert_before(new(ctx) ir_assignment(lhs, ret->value, NULL));
+ ret->remove();
+ } else {
+ /* un-valued return has to be the last return, or we shouldn't
+ * have reached here. (see can_inline()).
+ */
+ assert(!ret->next->is_tail_sentinal());
+ }
+ }
+}
+
ir_rvalue *
ir_call::generate_inline(ir_instruction *next_ir)
{
@@ -127,11 +148,12 @@ ir_call::generate_inline(ir_instruction *next_ir)
/* Generate a new variable for the parameter. */
parameters[i] = (ir_variable *)sig_param->clone(ht);
+ parameters[i]->mode = ir_var_auto;
next_ir->insert_before(parameters[i]);
/* Move the actual param into our param variable if it's an 'in' type. */
- if (parameters[i]->mode == ir_var_in ||
- parameters[i]->mode == ir_var_inout) {
+ if (sig_param->mode == ir_var_in ||
+ sig_param->mode == ir_var_inout) {
ir_assignment *assign;
assign = new(ctx) ir_assignment(new(ctx) ir_dereference_variable(parameters[i]),
@@ -146,8 +168,10 @@ ir_call::generate_inline(ir_instruction *next_ir)
/* Generate the inlined body of the function. */
foreach_iter(exec_list_iterator, iter, callee->body) {
ir_instruction *ir = (ir_instruction *)iter.get();
+ ir_instruction *new_ir = ir->clone(ht);
- next_ir->insert_before(ir->clone(ht));
+ next_ir->insert_before(new_ir);
+ visit_tree(new_ir, replace_return_with_assignment, retval);
}
/* Copy back the value of any 'out' parameters from the function body
diff --git a/ir_hierarchical_visitor.cpp b/ir_hierarchical_visitor.cpp
index 63ce8784ad..0d520b127f 100644
--- a/ir_hierarchical_visitor.cpp
+++ b/ir_hierarchical_visitor.cpp
@@ -268,3 +268,17 @@ ir_hierarchical_visitor::run(exec_list *instructions)
break;
}
}
+
+
+void
+visit_tree(ir_instruction *ir,
+ void (*callback)(class ir_instruction *ir, void *data),
+ void *data)
+{
+ ir_hierarchical_visitor v;
+
+ v.callback = callback;
+ v.data = data;
+
+ ir->accept(&v);
+}
diff --git a/ir_hierarchical_visitor.h b/ir_hierarchical_visitor.h
index e741155e19..8b9e49dab1 100644
--- a/ir_hierarchical_visitor.h
+++ b/ir_hierarchical_visitor.h
@@ -139,7 +139,6 @@ public:
*/
void run(struct exec_list *instructions);
-protected:
/**
* Callback function that is invoked on entry to each node visited.
*
@@ -156,4 +155,8 @@ protected:
void *data;
};
+void visit_tree(ir_instruction *ir,
+ void (*callback)(class ir_instruction *ir, void *data),
+ void *data);
+
#endif /* IR_HIERARCHICAL_VISITOR_H */
diff --git a/ir_print_visitor.cpp b/ir_print_visitor.cpp
index f15ffb6614..be5a843f67 100644
--- a/ir_print_visitor.cpp
+++ b/ir_print_visitor.cpp
@@ -92,7 +92,7 @@ void ir_print_visitor::visit(ir_variable *ir)
cent, inv, mode[ir->mode], interp[ir->interpolation]);
print_type(ir->type);
- printf(" %s)", ir->name);
+ printf(" %s@%p)", ir->name, ir);
}
@@ -220,7 +220,8 @@ void ir_print_visitor::visit(ir_swizzle *ir)
void ir_print_visitor::visit(ir_dereference_variable *ir)
{
- printf("(var_ref %s) ", ir->variable_referenced()->name);
+ ir_variable *var = ir->variable_referenced();
+ printf("(var_ref %s@%p) ", var->name, var);
}