freedreno/ir3: be more clever with if/else jumps
authorRob Clark <robdclark@gmail.com>
Mon, 15 Jan 2018 20:57:52 +0000 (15:57 -0500)
committerRob Clark <robdclark@gmail.com>
Sat, 10 Feb 2018 19:54:58 +0000 (14:54 -0500)
Try to clean up things like:

  br !p0.x #2
  br p0.x #something

to eliminate the first branch.

Signed-off-by: Rob Clark <robdclark@gmail.com>
src/gallium/drivers/freedreno/ir3/ir3_legalize.c

index 9d443d72c33b06c61407a38e2ae6252ea1bcfd77..239bfc28826bb042572a52e9286f9692a9c5cefa 100644 (file)
@@ -335,7 +335,22 @@ resolve_jump(struct ir3_instruction *instr)
        target = list_first_entry(&tblock->instr_list,
                                struct ir3_instruction, node);
 
-       if ((!target) || (target->ip == (instr->ip + 1))) {
+       /* TODO maybe a less fragile way to do this.  But we are expecting
+        * a pattern from sched_block() that looks like:
+        *
+        *   br !p0.x, #else-block
+        *   br p0.x, #if-block
+        *
+        * if the first branch target is +2, or if 2nd branch target is +1
+        * then we can just drop the jump.
+        */
+       unsigned next_block;
+       if (instr->cat0.inv == true)
+               next_block = 2;
+       else
+               next_block = 1;
+
+       if ((!target) || (target->ip == (instr->ip + next_block))) {
                list_delinit(&instr->node);
                return true;
        } else {