diff options
author | Rob Clark <[email protected]> | 2019-06-29 04:52:47 -0700 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2019-08-28 15:25:25 -0700 |
commit | 6af70aa2b457d2c2dc8c7818f71459f407f99eae (patch) | |
tree | 590ef3300414cc2c13197e85c51ad6d4af2da4ae /src | |
parent | 06bc4875fff8ad144dbebebe53241da4655aecc6 (diff) |
freedreno/ir3: maintain predecessors/successors
While resolving jumps to skip intermediate jumps from the structured
CFG, maintain the successors and predecessors correctly.
Signed-off-by: Rob Clark <[email protected]>
Reviewed-by: Eric Anholt <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/freedreno/ir3/ir3_legalize.c | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/src/freedreno/ir3/ir3_legalize.c b/src/freedreno/ir3/ir3_legalize.c index e46d1214d60..2fb7f9de6f1 100644 --- a/src/freedreno/ir3/ir3_legalize.c +++ b/src/freedreno/ir3/ir3_legalize.c @@ -400,6 +400,47 @@ resolve_dest_block(struct ir3_block *block) return block; } +static void +remove_unused_block(struct ir3_block *old_target) +{ + list_delinit(&old_target->node); + + /* cleanup dangling predecessors: */ + for (unsigned i = 0; i < ARRAY_SIZE(old_target->successors); i++) { + if (old_target->successors[i]) { + struct ir3_block *succ = old_target->successors[i]; + _mesa_set_remove_key(succ->predecessors, old_target); + } + } +} + +static void +retarget_jump(struct ir3_instruction *instr, struct ir3_block *new_target) +{ + struct ir3_block *old_target = instr->cat0.target; + struct ir3_block *cur_block = instr->block; + + /* update current blocks successors to reflect the retargetting: */ + if (cur_block->successors[0] == old_target) { + cur_block->successors[0] = new_target; + } else { + debug_assert(cur_block->successors[1] == old_target); + cur_block->successors[1] = new_target; + } + + /* update new target's predecessors: */ + _mesa_set_add(new_target->predecessors, cur_block); + + /* and remove old_target's predecessor: */ + debug_assert(_mesa_set_search(old_target->predecessors, cur_block)); + _mesa_set_remove_key(old_target->predecessors, cur_block); + + if (old_target->predecessors->entries == 0) + remove_unused_block(old_target); + + instr->cat0.target = new_target; +} + static bool resolve_jump(struct ir3_instruction *instr) { @@ -408,8 +449,7 @@ resolve_jump(struct ir3_instruction *instr) struct ir3_instruction *target; if (tblock != instr->cat0.target) { - list_delinit(&instr->cat0.target->node); - instr->cat0.target = tblock; + retarget_jump(instr, tblock); return true; } |