summaryrefslogtreecommitdiffstats
path: root/src/glsl/ir_expression_flattening.cpp
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2010-07-12 10:48:22 -0700
committerEric Anholt <[email protected]>2010-07-12 12:02:32 -0700
commit5723e5bb8b73cd2a3b77d750972e3d0b4d0d0ff8 (patch)
tree686153f4fdf97b398ce1d443171a9995ea1c04ee /src/glsl/ir_expression_flattening.cpp
parentd2afc874452a84965ee71c96f80e1d124c211ff4 (diff)
glsl2: Flatten out expressions that are the child of an assignment rhs.
This feels a little odd, but it will be useful for ir_mat_to_vec, where I want to see a plain assignment of the expression to a variable, not to a writemasked array dereference with a call as the array index.
Diffstat (limited to 'src/glsl/ir_expression_flattening.cpp')
-rw-r--r--src/glsl/ir_expression_flattening.cpp26
1 files changed, 19 insertions, 7 deletions
diff --git a/src/glsl/ir_expression_flattening.cpp b/src/glsl/ir_expression_flattening.cpp
index 5ba24e390b4..0f10b671936 100644
--- a/src/glsl/ir_expression_flattening.cpp
+++ b/src/glsl/ir_expression_flattening.cpp
@@ -57,9 +57,11 @@ public:
virtual ir_visitor_status visit_enter(ir_function_signature *);
virtual ir_visitor_status visit_enter(ir_if *);
virtual ir_visitor_status visit_enter(ir_loop *);
+ virtual ir_visitor_status visit_leave(ir_assignment *);
virtual ir_visitor_status visit_leave(ir_expression *);
virtual ir_visitor_status visit_leave(ir_swizzle *);
+ ir_rvalue *operand_to_temp(ir_rvalue *val);
bool (*predicate)(ir_instruction *ir);
ir_instruction *base_ir;
};
@@ -77,13 +79,16 @@ do_expression_flattening(exec_list *instructions,
}
-static ir_rvalue *
-operand_to_temp(ir_instruction *base_ir, ir_rvalue *ir)
+ir_rvalue *
+ir_expression_flattening_visitor::operand_to_temp(ir_rvalue *ir)
{
void *ctx = talloc_parent(base_ir);
ir_variable *var;
ir_assignment *assign;
+ if (!this->predicate(ir))
+ return ir;
+
var = new(ctx) ir_variable(ir->type, "flattening_tmp");
base_ir->insert_before(var);
@@ -131,20 +136,27 @@ ir_expression_flattening_visitor::visit_leave(ir_expression *ir)
/* If the operand matches the predicate, then we'll assign its
* value to a temporary and deref the temporary as the operand.
*/
- if (this->predicate(ir->operands[operand])) {
- ir->operands[operand] = operand_to_temp(base_ir,
- ir->operands[operand]);
- }
+ ir->operands[operand] = operand_to_temp(ir->operands[operand]);
}
return visit_continue;
}
ir_visitor_status
+ir_expression_flattening_visitor::visit_leave(ir_assignment *ir)
+{
+ ir->rhs = operand_to_temp(ir->rhs);
+ if (ir->condition)
+ ir->condition = operand_to_temp(ir->condition);
+
+ return visit_continue;
+}
+
+ir_visitor_status
ir_expression_flattening_visitor::visit_leave(ir_swizzle *ir)
{
if (this->predicate(ir->val)) {
- ir->val = operand_to_temp(this->base_ir, ir->val);
+ ir->val = operand_to_temp(ir->val);
}
return visit_continue;