slang: if/else/break & if/else/continue work for unrolled loops
This commit is contained in:
parent
1342664434
commit
989856bde4
|
@ -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.
|
* Unroll a for-loop.
|
||||||
* First we determine the number of iterations to unroll.
|
* 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_ir_node *n, *root = NULL;
|
||||||
slang_atom varId;
|
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) {
|
if (oper->children[0].type == SLANG_OPER_BLOCK_NO_NEW_SCOPE) {
|
||||||
/* for (int i=0; ... */
|
/* for (int i=0; ... */
|
||||||
slang_variable *var;
|
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 */
|
/* make a copy of the loop body */
|
||||||
body = slang_operation_new(1);
|
body = slang_operation_new(1);
|
||||||
if (!body)
|
if (!body) {
|
||||||
|
_unroll_loop_dec( A );
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!slang_operation_copy(body, &oper->children[3]))
|
if (!slang_operation_copy(body, &oper->children[3])) {
|
||||||
|
_unroll_loop_dec( A );
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* in body, replace instances of 'varId' with literal 'iter' */
|
/* 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) {
|
if (!oldVar) {
|
||||||
/* undeclared loop variable */
|
/* undeclared loop variable */
|
||||||
slang_operation_delete(body);
|
slang_operation_delete(body);
|
||||||
|
_unroll_loop_dec( A );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2642,14 +2664,18 @@ _slang_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper)
|
||||||
|
|
||||||
/* do IR codegen for body */
|
/* do IR codegen for body */
|
||||||
n = _slang_gen_operation(A, body);
|
n = _slang_gen_operation(A, body);
|
||||||
if (!n)
|
if (!n) {
|
||||||
|
_unroll_loop_dec( A );
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
root = new_seq(root, n);
|
root = new_seq(root, n);
|
||||||
|
|
||||||
slang_operation_delete(body);
|
slang_operation_delete(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_unroll_loop_dec( A );
|
||||||
|
|
||||||
return root;
|
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)
|
if (is_operation_type(&oper->children[1], SLANG_OPER_BREAK)
|
||||||
&& !haveElseClause) {
|
&& !haveElseClause) {
|
||||||
/* Special case: generate a conditional break */
|
/* Special case: generate a conditional break */
|
||||||
if (!A->CurLoop) /* probably trying to unroll */
|
if (!A->CurLoop && A->UnrollLoop) /* trying to unroll */
|
||||||
return NULL;
|
return NULL;
|
||||||
ifBody = new_break_if_true(A->CurLoop, cond);
|
ifBody = new_break_if_true(A->CurLoop, cond);
|
||||||
return ifBody;
|
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)
|
else if (is_operation_type(&oper->children[1], SLANG_OPER_CONTINUE)
|
||||||
&& !haveElseClause) {
|
&& !haveElseClause) {
|
||||||
/* Special case: generate a conditional continue */
|
/* Special case: generate a conditional continue */
|
||||||
if (!A->CurLoop) /* probably trying to unroll */
|
if (!A->CurLoop && A->UnrollLoop) /* trying to unroll */
|
||||||
return NULL;
|
return NULL;
|
||||||
ifBody = new_cont_if_true(A->CurLoop, cond);
|
ifBody = new_cont_if_true(A->CurLoop, cond);
|
||||||
return ifBody;
|
return ifBody;
|
||||||
|
@ -2802,6 +2828,8 @@ _slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper)
|
||||||
else {
|
else {
|
||||||
/* general case */
|
/* general case */
|
||||||
ifBody = _slang_gen_operation(A, &oper->children[1]);
|
ifBody = _slang_gen_operation(A, &oper->children[1]);
|
||||||
|
if (!ifBody)
|
||||||
|
return NULL;
|
||||||
if (haveElseClause)
|
if (haveElseClause)
|
||||||
elseBody = _slang_gen_operation(A, &oper->children[2]);
|
elseBody = _slang_gen_operation(A, &oper->children[2]);
|
||||||
else
|
else
|
||||||
|
@ -4014,13 +4042,15 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper)
|
||||||
return _slang_gen_while(A, oper);
|
return _slang_gen_while(A, oper);
|
||||||
case SLANG_OPER_BREAK:
|
case SLANG_OPER_BREAK:
|
||||||
if (!A->CurLoop) {
|
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 NULL;
|
||||||
}
|
}
|
||||||
return new_break(A->CurLoop);
|
return new_break(A->CurLoop);
|
||||||
case SLANG_OPER_CONTINUE:
|
case SLANG_OPER_CONTINUE:
|
||||||
if (!A->CurLoop) {
|
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 NULL;
|
||||||
}
|
}
|
||||||
return _slang_gen_continue(A, oper);
|
return _slang_gen_continue(A, oper);
|
||||||
|
|
|
@ -42,6 +42,7 @@ typedef struct slang_assemble_ctx_
|
||||||
struct slang_label_ *curFuncEndLabel;
|
struct slang_label_ *curFuncEndLabel;
|
||||||
struct slang_ir_node_ *CurLoop;
|
struct slang_ir_node_ *CurLoop;
|
||||||
struct slang_function_ *CurFunction;
|
struct slang_function_ *CurFunction;
|
||||||
|
GLuint UnrollLoop;
|
||||||
} slang_assemble_ctx;
|
} slang_assemble_ctx;
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue