freedreno/ir3: add helpers to move instructions
[mesa.git] / src / freedreno / ir3 / ir3_group.c
index 4fc236708d701844ce82db2103a1261fef2f14b1..61ecd5320b315f3f494fcae501ffd5c575ea1c29 100644 (file)
@@ -34,7 +34,9 @@ static void
 insert_mov(struct ir3_instruction *collect, int idx)
 {
        struct ir3_instruction *src = ssa(collect->regs[idx+1]);
-       struct ir3_instruction *mov = ir3_MOV(src->block, src, TYPE_F32);
+       struct ir3_instruction *mov = ir3_MOV(src->block, src,
+               (collect->regs[idx+1]->flags & IR3_REG_HALF) ? TYPE_U16 : TYPE_U32);
+
        collect->regs[idx+1]->instr = mov;
 
        /* if collect and src are in the same block, move the inserted mov
@@ -42,8 +44,7 @@ insert_mov(struct ir3_instruction *collect, int idx)
         * it should be safe to leave at the end of the block it is in:
         */
        if (src->block == collect->block) {
-               list_delinit(&mov->node);
-               list_addtail(&mov->node, &collect->node);
+               ir3_instr_move_before(mov, collect);
        }
 }
 
@@ -139,45 +140,51 @@ restart:
        }
 }
 
-static void
+static bool
 instr_find_neighbors(struct ir3_instruction *instr)
 {
-       struct ir3_instruction *src;
+       bool progress = false;
 
        if (ir3_instr_check_mark(instr))
-               return;
+               return false;
 
-       if (instr->opc == OPC_META_COLLECT)
+       if (instr->opc == OPC_META_COLLECT) {
                group_collect(instr);
+               progress = true;
+       }
 
        foreach_ssa_src (src, instr)
-               instr_find_neighbors(src);
+               progress |= instr_find_neighbors(src);
+
+       return progress;
 }
 
-static void
+static bool
 find_neighbors(struct ir3 *ir)
 {
+       bool progress = false;
        unsigned i;
 
-       struct ir3_instruction *out;
        foreach_output (out, ir)
-               instr_find_neighbors(out);
+               progress |= instr_find_neighbors(out);
 
        foreach_block (block, &ir->block_list) {
                for (i = 0; i < block->keeps_count; i++) {
                        struct ir3_instruction *instr = block->keeps[i];
-                       instr_find_neighbors(instr);
+                       progress |= instr_find_neighbors(instr);
                }
 
                /* We also need to account for if-condition: */
                if (block->condition)
-                       instr_find_neighbors(block->condition);
+                       progress |= instr_find_neighbors(block->condition);
        }
+
+       return progress;
 }
 
-void
+bool
 ir3_group(struct ir3 *ir)
 {
        ir3_clear_mark(ir);
-       find_neighbors(ir);
+       return find_neighbors(ir);
 }