Mesa (master): slang: if/else/break & if/else/ continue work for unrolled loops

Alan Hourihane alanh at kemper.freedesktop.org
Thu Mar 19 10:17:38 UTC 2009


Module: Mesa
Branch: master
Commit: 989856bde47d699d7e18798df4013fbf962e1d4b
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=989856bde47d699d7e18798df4013fbf962e1d4b

Author: Alan Hourihane <alanh at vmware.com>
Date:   Thu Mar 19 10:16:28 2009 +0000

slang: if/else/break & if/else/continue work for unrolled loops

---

 src/mesa/shader/slang/slang_codegen.c |   44 +++++++++++++++++++++++++++-----
 src/mesa/shader/slang/slang_codegen.h |    1 +
 2 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index e98d9d9..6c8c8c1 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -2575,6 +2575,20 @@ _slang_can_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper)
 }
 
 
+static void
+_unroll_loop_inc(slang_assemble_ctx * A)
+{
+   A->UnrollLoop++;
+}
+
+
+static void
+_unroll_loop_dec(slang_assemble_ctx * A)
+{
+   A->UnrollLoop--;
+}
+
+
 /**
  * Unroll a for-loop.
  * First we determine the number of iterations to unroll.
@@ -2591,6 +2605,9 @@ _slang_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper)
    slang_ir_node *n, *root = NULL;
    slang_atom varId;
 
+   /* Set flag so code generator knows we're unrolling loops */
+   _unroll_loop_inc( A );
+
    if (oper->children[0].type == SLANG_OPER_BLOCK_NO_NEW_SCOPE) {
       /* for (int i=0; ... */
       slang_variable *var;
@@ -2613,11 +2630,15 @@ _slang_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper)
 
       /* make a copy of the loop body */
       body = slang_operation_new(1);
-      if (!body)
+      if (!body) {
+         _unroll_loop_dec( A );
          return NULL;
+      }
 
-      if (!slang_operation_copy(body, &oper->children[3]))
+      if (!slang_operation_copy(body, &oper->children[3])) {
+         _unroll_loop_dec( A );
          return NULL;
+      }
 
       /* in body, replace instances of 'varId' with literal 'iter' */
       {
@@ -2628,6 +2649,7 @@ _slang_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper)
          if (!oldVar) {
             /* undeclared loop variable */
             slang_operation_delete(body);
+            _unroll_loop_dec( A );
             return NULL;
          }
 
@@ -2642,14 +2664,18 @@ _slang_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper)
 
       /* do IR codegen for body */
       n = _slang_gen_operation(A, body);
-      if (!n)
+      if (!n) {
+         _unroll_loop_dec( A );
          return NULL;
+      }
 
       root = new_seq(root, n);
 
       slang_operation_delete(body);
    }
 
+   _unroll_loop_dec( A );
+
    return root;
 }
 
@@ -2786,7 +2812,7 @@ _slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper)
    if (is_operation_type(&oper->children[1], SLANG_OPER_BREAK)
        && !haveElseClause) {
       /* Special case: generate a conditional break */
-      if (!A->CurLoop) /* probably trying to unroll */
+      if (!A->CurLoop && A->UnrollLoop) /* trying to unroll */
          return NULL;
       ifBody = new_break_if_true(A->CurLoop, cond);
       return ifBody;
@@ -2794,7 +2820,7 @@ _slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper)
    else if (is_operation_type(&oper->children[1], SLANG_OPER_CONTINUE)
             && !haveElseClause) {
       /* Special case: generate a conditional continue */
-      if (!A->CurLoop) /* probably trying to unroll */
+      if (!A->CurLoop && A->UnrollLoop) /* trying to unroll */
          return NULL;
       ifBody = new_cont_if_true(A->CurLoop, cond);
       return ifBody;
@@ -2802,6 +2828,8 @@ _slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper)
    else {
       /* general case */
       ifBody = _slang_gen_operation(A, &oper->children[1]);
+      if (!ifBody)
+         return NULL;
       if (haveElseClause)
          elseBody = _slang_gen_operation(A, &oper->children[2]);
       else
@@ -4014,13 +4042,15 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper)
       return _slang_gen_while(A, oper);
    case SLANG_OPER_BREAK:
       if (!A->CurLoop) {
-         slang_info_log_error(A->log, "'break' not in loop");
+         if (!A->UnrollLoop)
+            slang_info_log_error(A->log, "'break' not in loop");
          return NULL;
       }
       return new_break(A->CurLoop);
    case SLANG_OPER_CONTINUE:
       if (!A->CurLoop) {
-         slang_info_log_error(A->log, "'continue' not in loop");
+         if (!A->UnrollLoop)
+            slang_info_log_error(A->log, "'continue' not in loop");
          return NULL;
       }
       return _slang_gen_continue(A, oper);
diff --git a/src/mesa/shader/slang/slang_codegen.h b/src/mesa/shader/slang/slang_codegen.h
index f2daa03..e812c1f 100644
--- a/src/mesa/shader/slang/slang_codegen.h
+++ b/src/mesa/shader/slang/slang_codegen.h
@@ -42,6 +42,7 @@ typedef struct slang_assemble_ctx_
    struct slang_label_ *curFuncEndLabel;
    struct slang_ir_node_ *CurLoop;
    struct slang_function_ *CurFunction;
+   GLuint UnrollLoop;
 } slang_assemble_ctx;
 
 




More information about the mesa-commit mailing list