[Mesa-dev] [PATCH 03/15] i965/cfg: Rework to make IF & ELSE blocks flow into ENDIF.
Matt Turner
mattst88 at gmail.com
Wed Dec 4 15:11:02 PST 2013
On Wed, Dec 4, 2013 at 1:17 PM, Eric Anholt <eric at anholt.net> wrote:
> Matt Turner <mattst88 at gmail.com> writes:
>
>> Previously we made the basic block following an ENDIF instruction a
>> successor of the basic blocks ending with IF and ELSE. The PRM says that
>> IF and ELSE instructions jump *to* the ENDIF, rather than over it.
>>
>> This should be immaterial to dataflow analysis, except for if, break,
>> endif sequences:
>>
>> START B1 <-B0 <-B9
>> 0x00000100: cmp.g.f0(8) null g15<8,8,1>F g4<0,1,0>F
>> 0x00000110: (+f0) if(8) 0 0 null 0x00000000UD
>> END B1 ->B2 ->B4
>> START B2 <-B1
>> break
>> 0x00000120: break(8) 0 0 null 0D
>> END B2 ->B10
>> START B3
>> 0x00000130: endif(8) 2 null 0x00000002UD
>> END B3 ->B4
>>
>> The ENDIF block would have no parents, so dataflow analysis would
>> generate incorrect results, preventing copy propagation from eliminating
>> some instructions.
>>
>> This patch changes the CFG to make ENDIF start rather than end basic
>> blocks, so that it can be the jump target of the IF and ELSE
>> instructions.
>>
>> It helps three programs (including two fs8/fs16 pairs) and hurts a
>> single fs8/fs16 pair.
>>
>> total instructions in shared programs: 1561126 -> 1561066 (-0.00%)
>> instructions in affected programs: 983 -> 923 (-6.10%)
>>
>> More importantly, it allows copy propagation to handle more cases.
>> Disabling the register_coalesce() pass before this patch hurts 58
>> programs, while afterward it only hurts 11 programs.
>> ---
>> src/mesa/drivers/dri/i965/brw_cfg.cpp | 46 +++++++++++++++++++++++++----------
>> 1 file changed, 33 insertions(+), 13 deletions(-)
>>
>> diff --git a/src/mesa/drivers/dri/i965/brw_cfg.cpp b/src/mesa/drivers/dri/i965/brw_cfg.cpp
>> index 548b458..83c3c34 100644
>> --- a/src/mesa/drivers/dri/i965/brw_cfg.cpp
>> +++ b/src/mesa/drivers/dri/i965/brw_cfg.cpp
>> @@ -133,10 +133,7 @@ cfg_t::create(void *parent_mem_ctx, exec_list *instructions)
>>
>> cur_if = cur;
>> cur_else = NULL;
>> - /* Set up the block just after the endif. Don't know when exactly
>> - * it will start, yet.
>> - */
>> - cur_endif = new_block();
>> + cur_endif = NULL;
>>
>> /* Set up our immediately following block, full of "then"
>> * instructions.
>> @@ -149,26 +146,49 @@ cfg_t::create(void *parent_mem_ctx, exec_list *instructions)
>> break;
>>
>> case BRW_OPCODE_ELSE:
>> - cur->add_successor(mem_ctx, cur_endif);
>> + cur_else = cur;
>>
>> next = new_block();
>> next->start = (backend_instruction *)inst->next;
>> cur_if->add_successor(mem_ctx, next);
>> - cur_else = next;
>>
>> set_next_block(next);
>> break;
>>
>> case BRW_OPCODE_ENDIF: {
>> - cur_endif->start = (backend_instruction *)inst->next;
>> - cur->add_successor(mem_ctx, cur_endif);
>> - set_next_block(cur_endif);
>> + backend_instruction *prev_inst = (backend_instruction *)inst->prev;
>> + switch (prev_inst->opcode) {
>> + case BRW_OPCODE_IF:
>> + case BRW_OPCODE_ELSE:
>> + case BRW_OPCODE_WHILE:
>> + case BRW_OPCODE_DO:
>> + case BRW_OPCODE_BREAK:
>> + case BRW_OPCODE_CONTINUE:
>> + /* New block was just created; use it. */
>> + cur_endif = cur;
>> + break;
>
> Instead of the opcode switch for this test, couldn't you just do "if
> cur->start == inst"?
Yes, that is better.
> Other than that, this series is:
>
> Reviewed-by: Eric Anholt <eric at anholt.net>
Thanks!
More information about the mesa-dev
mailing list