aboutsummaryrefslogtreecommitdiffstats
path: root/src/glsl/ir_reader.cpp
diff options
context:
space:
mode:
authorPaul Berry <[email protected]>2013-11-28 08:13:41 -0800
committerPaul Berry <[email protected]>2013-12-09 10:54:33 -0800
commite00b93a1f7b4bc7f5e887591c000524e13f80826 (patch)
tree4bfdfa0f56747019aed8c427fb3349adc1e53e7e /src/glsl/ir_reader.cpp
parent2c17f97fe6a40e4a963fb4eec0ea0555f562b1be (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.cpp30
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;