i965/cfg: Make DO instruction begin a basic block.
authorMatt Turner <mattst88@gmail.com>
Sat, 17 May 2014 18:53:45 +0000 (11:53 -0700)
committerMatt Turner <mattst88@gmail.com>
Sun, 25 May 2014 06:03:22 +0000 (23:03 -0700)
The DO instruction doesn't exist on Gen6+. Since before this commit, DO
always ended a basic block, if it also happened to start one (e.g., a
while loop inside an if statement) the block containing only the DO
would actually contain no hardware instructions.

Pre-Gen6's WHILE instructions jumps to the instruction following the DO,
so strictly speaking we won't be modeling that properly, but I claim
there is actually no functional difference.

This will simplify an upcoming change where we want to mark the first
hardware instruction in the loop as beginning a block, and the last
instruction before the loop as ending one.

Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/drivers/dri/i965/brw_cfg.cpp

index a806714..6bf99f1 100644 (file)
@@ -98,7 +98,7 @@ cfg_t::cfg_t(exec_list *instructions)
    bblock_t *cur_if = NULL;    /**< BB ending with IF. */
    bblock_t *cur_else = NULL;  /**< BB ending with ELSE. */
    bblock_t *cur_endif = NULL; /**< BB starting with ENDIF. */
-   bblock_t *cur_do = NULL;    /**< BB ending with DO. */
+   bblock_t *cur_do = NULL;    /**< BB starting with DO. */
    bblock_t *cur_while = NULL; /**< BB immediately following WHILE. */
    exec_list if_stack, else_stack, do_stack, while_stack;
    bblock_t *next;
@@ -205,15 +205,18 @@ cfg_t::cfg_t(exec_list *instructions)
          */
         cur_while = new_block();
 
-        /* Set up our immediately following block, full of "then"
-         * instructions.
-         */
-        next = new_block();
-        next->start = (backend_instruction *)inst->next;
-        cur->add_successor(mem_ctx, next);
-        cur_do = next;
+         if (cur->start == inst) {
+            /* New block was just created; use it. */
+            cur_do = cur;
+         } else {
+            cur_do = new_block();
+            cur_do->start = inst;
 
-        set_next_block(&cur, next, ip);
+            cur->end = (backend_instruction *)inst->prev;
+            cur->add_successor(mem_ctx, cur_do);
+
+            set_next_block(&cur, cur_do, ip - 1);
+         }
         break;
 
       case BRW_OPCODE_CONTINUE: