[Mesa-dev] [PATCH 6/6] glsl: Generate IR for switch statements
Kenneth Graunke
kenneth at whitecape.org
Mon Jun 27 17:15:04 PDT 2011
On 06/24/2011 05:11 PM, Dan McCabe wrote:
> Looking at a translation of my canonical example:
>
> switch (expr) {
> case c0:
> case c1:
> stmt0;
> case c2:
> case c3:
> stmt1;
> break;
> case c4:
> default:
> stmt2;
> }
>
> We can translated this into:
>
> int test_val_tmp = expr;
> bool is_fallthru_tmp = false;
> bool is_break_tmp = false;
>
> if (test_val_tmp == c0) {
> is_fallthru_tmp = true;
> }
> if (test_val_tmp == c1) {
> is_fallthru_tmp = true;
> }
> if (is_break_tmp) {
> is_fallthru_tmp = false;
> }
> if (is_fallthru_tmp) {
> stmt0;
> }
>
> if (test_val_tmp == c2) {
> is_fallthru_tmp = true;
> }
> if (test_val_tmp == c3) {
> is_fallthru_tmp = true;
> }
> if (is_break_tmp) {
> is_fallthru_tmp = false;
> }
> if (is_fallthru_tmp) {
> stmt1;
> is_break_tmp = true; // break stmt
> }
>
> if (test_val_tmp == c4) {
> is_fallthru_tmp = true;
> }
> is_fallthru_tmp = true; // default
> if (is_break_tmp) {
> is_fallthru_tmp = false;
> }
> if (is_fallthru_tmp) {
> stmt2;
> }
I must admit, I'm not particularly crazy about the amount of
if-statements being generated here. A couple of ideas...
1. Use conditional moves:
(assign (ir_expression all_equal (var_ref test_val_tmp) c0) ; condition
(var_ref is_fallthru_tmp) ; assignee
(constant bool (1))) ; true
Then again Ian's new optimization pass should do this for us, so maybe
leaving it as if-statements is fine.
Since we'd have two conditional moves (for c0 and c1) with the same
target and value, it'd be nice to combine them...but that sounds like a
pretty obscure optimization pass.
2. Use ORs:
is_fallthru_tmp = false;
is_fallthru_tmp = is_fallthru_tmp || test_val_tmp == c0;
is_fallthru_tmp = is_fallthru_tmp || test_val_tmp == c1;
This seems somewhat easier to optimize...I imagine tree-grafting,
constant/copy propagation, etc. might be able to reduce this to:
is_fallthru_tmp = test_val_tmp == c0 || test_val_tmp == c1;
Again, I'm not sure. Ian, do you have an opinion?
In the end, this may be a moot point---we eventually want to take
advantage of hardware jump instructions. When switching on a uniform
(I'm guessing this is common), all the channels would take the same
path, so a simple ADD to the IP would work. Even for non-uniform
control flow, I suspect we could use the Gen "break" instruction, which
will jump if all channels take the path. But that's for later.
--Kenneth
More information about the mesa-dev
mailing list