diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2023-01-29 10:37:19 -1000 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2023-03-01 07:33:27 -1000 |
commit | 4d89d0bb8f01060b18f94d84c2dcea573bdd1381 (patch) | |
tree | 2af1404d8d929fbced3dad1182d23f6371c6fdf8 /tcg | |
parent | 9b1890ad901bd22352b8a9598220df51fe8b0d41 (diff) | |
download | qemu-4d89d0bb8f01060b18f94d84c2dcea573bdd1381.zip qemu-4d89d0bb8f01060b18f94d84c2dcea573bdd1381.tar.gz qemu-4d89d0bb8f01060b18f94d84c2dcea573bdd1381.tar.bz2 |
tcg: Remove branch-to-next regardless of reference count
Just because the label reference count is more than 1 does
not mean we cannot remove a branch-to-next. By doing this
first, the label reference count may drop to 0, and then
the label itself gets removed as before.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'tcg')
-rw-r--r-- | tcg/tcg.c | 33 |
1 files changed, 17 insertions, 16 deletions
@@ -2637,7 +2637,7 @@ TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *old_op, /* Reachable analysis : remove unreachable code. */ static void reachable_code_pass(TCGContext *s) { - TCGOp *op, *op_next; + TCGOp *op, *op_next, *op_prev; bool dead = false; QTAILQ_FOREACH_SAFE(op, &s->ops, link, op_next) { @@ -2647,6 +2647,22 @@ static void reachable_code_pass(TCGContext *s) switch (op->opc) { case INDEX_op_set_label: label = arg_label(op->args[0]); + + /* + * Optimization can fold conditional branches to unconditional. + * If we find a label which is preceded by an unconditional + * branch to next, remove the branch. We couldn't do this when + * processing the branch because any dead code between the branch + * and label had not yet been removed. + */ + op_prev = QTAILQ_PREV(op, link); + if (op_prev->opc == INDEX_op_br && + label == arg_label(op_prev->args[0])) { + tcg_op_remove(s, op_prev); + /* Fall through means insns become live again. */ + dead = false; + } + if (label->refs == 0) { /* * While there is an occasional backward branch, virtually @@ -2660,21 +2676,6 @@ static void reachable_code_pass(TCGContext *s) /* Once we see a label, insns become live again. */ dead = false; remove = false; - - /* - * Optimization can fold conditional branches to unconditional. - * If we find a label with one reference which is preceded by - * an unconditional branch to it, remove both. This needed to - * wait until the dead code in between them was removed. - */ - if (label->refs == 1) { - TCGOp *op_prev = QTAILQ_PREV(op, link); - if (op_prev->opc == INDEX_op_br && - label == arg_label(op_prev->args[0])) { - tcg_op_remove(s, op_prev); - remove = true; - } - } } break; |