summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Paul <brianp@vmware.com>2009-06-23 10:57:59 -0600
committerBrian Paul <brianp@vmware.com>2009-06-23 10:57:59 -0600
commitd851413fdb525d450e802b5ff339604f4266c8e4 (patch)
tree41af8c47b4b327f17b9791668b1b936f900d6eab
parent4b8e307f4c97703d3acc15c50e17c729c7cf0ca3 (diff)
glsl: use _slang_loop_contains_continue_or_break() to check for unrolling
The previous test failed for nested loops.
-rw-r--r--src/mesa/shader/slang/slang_codegen.c41
1 files changed, 36 insertions, 5 deletions
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 64dfdaff7e..55f7c0e8fc 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -2367,7 +2367,41 @@ _slang_loop_contains_continue(const slang_operation *oper)
{
GLuint i;
for (i = 0; i < oper->num_children; i++) {
- if (_slang_loop_contains_continue(slang_oper_child((slang_operation *) oper, i)))
+ slang_operation *child =
+ slang_oper_child((slang_operation *) oper, i);
+ if (_slang_loop_contains_continue(child))
+ return GL_TRUE;
+ }
+ }
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Check if a loop contains a 'continue' or 'break' statement.
+ * Stop looking if we find a nested loop.
+ */
+static GLboolean
+_slang_loop_contains_continue_or_break(const slang_operation *oper)
+{
+ switch (oper->type) {
+ case SLANG_OPER_CONTINUE:
+ case SLANG_OPER_BREAK:
+ return GL_TRUE;
+ case SLANG_OPER_FOR:
+ case SLANG_OPER_DO:
+ case SLANG_OPER_WHILE:
+ /* stop upon finding a nested loop */
+ return GL_FALSE;
+ default:
+ /* recurse */
+ {
+ GLuint i;
+ for (i = 0; i < oper->num_children; i++) {
+ slang_operation *child =
+ slang_oper_child((slang_operation *) oper, i);
+ if (_slang_loop_contains_continue_or_break(child))
return GL_TRUE;
}
}
@@ -2799,11 +2833,8 @@ _slang_can_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper)
assert(oper->num_children == 4);
- if (_slang_find_node_type((slang_operation *) oper, SLANG_OPER_CONTINUE) ||
- _slang_find_node_type((slang_operation *) oper, SLANG_OPER_BREAK)) {
- /* dont't unroll loops containing continue/break statements */
+ if (_slang_loop_contains_continue_or_break(oper))
return GL_FALSE;
- }
/* children[0] must be either "int i=constant" or "i=constant" */
if (oper->children[0].type == SLANG_OPER_BLOCK_NO_NEW_SCOPE) {