Browse Source

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

tags/mesa_7_5_rc1
Alan Hourihane 17 years ago
parent
commit
989856bde4
2 changed files with 38 additions and 7 deletions
  1. 37
    7
      src/mesa/shader/slang/slang_codegen.c
  2. 1
    0
      src/mesa/shader/slang/slang_codegen.h

+ 37
- 7
src/mesa/shader/slang/slang_codegen.c View File

@@ -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);

+ 1
- 0
src/mesa/shader/slang/slang_codegen.h View File

@@ -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;



Loading…
Cancel
Save