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
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev