diff options
author | Paul Berry <[email protected]> | 2013-11-28 08:13:41 -0800 |
---|---|---|
committer | Paul Berry <[email protected]> | 2013-12-09 10:54:33 -0800 |
commit | e00b93a1f7b4bc7f5e887591c000524e13f80826 (patch) | |
tree | 4bfdfa0f56747019aed8c427fb3349adc1e53e7e /src/glsl/ir_reader.cpp | |
parent | 2c17f97fe6a40e4a963fb4eec0ea0555f562b1be (diff) |
glsl/loops: replace loop controls with a normative bound.
This patch replaces the ir_loop fields "from", "to", "increment",
"counter", and "cmp" with a single integer ("normative_bound") that
serves the same purpose.
I've used the name "normative_bound" to emphasize the fact that the
back-end is required to emit code to prevent the loop from running
more than normative_bound times. (By contrast, an "informative" bound
would be a bound that is informational only).
Reviewed-by: Jordan Justen <[email protected]>
Reviewed-by: Ian Romanick <[email protected]>
Diffstat (limited to 'src/glsl/ir_reader.cpp')
-rw-r--r-- | src/glsl/ir_reader.cpp | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/src/glsl/ir_reader.cpp b/src/glsl/ir_reader.cpp index 7fcb34d2390..72ce684b69c 100644 --- a/src/glsl/ir_reader.cpp +++ b/src/glsl/ir_reader.cpp @@ -488,18 +488,34 @@ ir_reader::read_if(s_expression *expr, ir_loop *loop_ctx) ir_loop * ir_reader::read_loop(s_expression *expr) { - s_expression *s_counter, *s_from, *s_to, *s_inc, *s_body; + s_expression *s_bound_expr, *s_body, *s_bound; - s_pattern pat[] = { "loop", s_counter, s_from, s_to, s_inc, s_body }; - if (!MATCH(expr, pat)) { - ir_read_error(expr, "expected (loop <counter> <from> <to> " - "<increment> <body>)"); + s_pattern loop_pat[] = { "loop", s_bound_expr, s_body }; + s_pattern no_bound_pat[] = { }; + s_pattern bound_pat[] = { s_bound }; + if (!MATCH(expr, loop_pat)) { + ir_read_error(expr, "expected (loop <bound> <body>)"); return NULL; } - // FINISHME: actually read the count/from/to fields. - ir_loop *loop = new(mem_ctx) ir_loop; + + if (MATCH(s_bound_expr, no_bound_pat)) { + loop->normative_bound = -1; + } else if (MATCH(s_bound_expr, bound_pat)) { + s_int *value = SX_AS_INT(s_bound); + if (value == NULL) { + ir_read_error(s_bound_expr, "malformed loop bound"); + delete loop; + return NULL; + } + loop->normative_bound = value->value(); + } else { + ir_read_error(s_bound_expr, "malformed loop bound"); + delete loop; + return NULL; + } + read_instructions(&loop->body_instructions, s_body, loop); if (state->error) { delete loop; |