tree 9438d45b06a69331e907e32e9dfe03c0842e65e2
parent 85beb39e14556cf02f58116fd287120cd1defbd5
author Dan McCabe <zen3d.linux@gmail.com> 1320711478 -0800
committer Dan McCabe <zen3d.linux@gmail.com> 1320712282 -0800

glsl: Generate IR for switch statements

Up until now modifying the GLSL compiler has been pretty straightforward.
This is where things get interesting. But still pretty straightforward.

Switch statements can be thought of a series of if/then/else statements.
Case labels are compared with the value of a test expression and the case
statements are executed if the comparison is true.

There are a couple of aspects of switch statements that complicate this simple
view of the world. The primary one is that cases can fall through sequentially
to subsequent case, unless a break statement is encountered, in which case,
the switch statement exits completely.

But break handling is further complicated by the fact that a break statement
can impact the exit of a loop. Thus, we need to coordinate break processing
between switch statements and loop statements.

The code generated by a switch statement maintains three temporary state
variables:
    int test_value;
    bool is_fallthru;
    bool is_break;

test_value is initialized to the value of the test expression at the head of
the switch statement. This is the value that case labels are compared against.

is_fallthru is used to sequentially fall through to subsequent cases and is
initialized to false. When a case label matches the test expression, this
state variable is set to true. It will also be forced to false if a break
statement has been encountered. This forcing to false on break MUST be
after every case test. In practice, we defer that forcing to immediately after
the last case comparison prior to executing a case statement, but that is
an optimization.

is_break is used to indicate that a break statement has been executed and is
initialized to false. When a break statement is encountered, it is set to true.
This state variable is then used to conditionally force is_fallthru to to false
to prevent subsequent case statements from executing.

Code generation for break statements depends on whether the break statement is
inside a switch statement or inside a loop statement. If it inside a loop
statement is inside a break statement, the same code as before gets generated.
But if a switch statement is inside a loop statement, code is emitted to set
the is_break state to true.

Just as ASTs for loop statements are managed in a stack-like
manner to handle nesting, we also add a bool to capture the innermost switch
or loop condition. Note that we still need to maintain a loop AST stack to
properly handle for-loop code generation on a continue statement. Technically,
we don't (yet) need a switch AST stack, but I am using one for orthogonality
with loop statements, in anticipation of future use. Note that a simple
boolean stack would have sufficed.

We will illustrate a switch statement with its analogous conditional code that
a switch statement corresponds to by examining an example.

Consider the following switch statement:
	switch (42) {
	case 0:
	case 1:
		gl_FragColor = vec4(1.0, 2.0, 3.0, 4.0);
	case 2:
	case 3:
		gl_FragColor = vec4(4.0, 3.0, 2.0, 1.0);
		break;
	case 4:
	default:
		gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
	}

Note that case 0 and case 1 fall through to cases 2 and 3 if they occur.

Note that case 4 and the default case must be reached explicitly, since cases
2 and 3 break at the end of their case.

Finally, note that case 4 and the default case don't break but simply fall
through to the end of the switch.

For this code, the equivalent code can be expressed as:
	int test_val = 42; // capture value of test expression
	bool is_fallthru = false; // prevent initial fall through
	bool is_break = false; // capture the execution of a break stmt

	is_fallthru |= (test_val == 0); // enable fallthru on case 0
	is_fallthru |= (test_val == 1); // enable fallthru on case 1
	is_fallthru &= !is_break; // inhibit fallthru on previous break
	if (is_fallthru) {
		gl_FragColor = vec4(1.0, 2.0, 3.0, 4.0);
	}

	is_fallthru |= (test_val == 2); // enable fallthru on case 2
	is_fallthru |= (test_val == 3); // enable fallthru on case 3
	is_fallthru &= !is_break; // inhibit fallthru on previous break
	if (is_fallthru) {
		gl_FragColor = vec4(4.0, 3.0, 2.0, 1.0);
		is_break = true; // inhibit all subsequent fallthru for break
	}

	is_fallthru |= (test_val == 4); // enable fallthru on case 4
	is_fallthru = true; // enable fallthru for default case
	is_fallthru &= !is_break; // inhibit fallthru on previous break
	if (is_fallthru) {
		gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
	}

The code generate for |= and &= uses the conditional assignment capabilities
of the IR.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
