[Mesa-dev] [PATCH 6/6] glsl: Generate IR for switch statements
Dan McCabe
zen3d.linux at gmail.com
Mon Jun 27 17:23:30 PDT 2011
On 06/27/2011 05:15 PM, Kenneth Graunke wrote:
> 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
Since I am just about to start modifying the IR generation, I'm open to
suggestion.
#1 looks like a better choice. But I might change my mind when I
actually get to modifying the code.
I originally considered #2, but the IR that was generated by such code
didn't look any better (i.e., you would up with a bunch of IF code
anyway). That is why I went the route I did.
More information about the mesa-dev
mailing list