summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Clark <robdclark@gmail.com>2018-01-15 15:57:52 -0500
committerRob Clark <robdclark@gmail.com>2018-02-10 14:54:58 -0500
commita5c28fe07b2822866aaedfe94362918904bd8869 (patch)
tree94342bd7c0057709117918f271f4d9a20856f663
parent44dd7dcd2fb0d59cf33bad5313bd45b583002ae4 (diff)
freedreno/ir3: be more clever with if/else jumps
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>
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_legalize.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_legalize.c b/src/gallium/drivers/freedreno/ir3/ir3_legalize.c
index 9d443d72c33..239bfc28826 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_legalize.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_legalize.c
@@ -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 {