qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] tcg: `reachable_code_pass()` remove empty else-branch


From: Anton Johansson
Subject: [PATCH] tcg: `reachable_code_pass()` remove empty else-branch
Date: Wed, 1 Mar 2023 15:22:21 +0100

This patch extends reachable_code_pass() to also deal with empty
else-branches of the form

  br $L0
  set_label $L1
  set_label $L0

converting them to

  set_label $L1

when $L0 is only referenced by the br op.  This type of empty-else
branch will be emitted by idef-parser in the Hexagon frontend once
CANCEL statements have been ignored.

Signed-off-by: Anton Johansson <anjo@rev.ng>
---
 tcg/tcg.c | 41 ++++++++++++++++++++++++++++++-----------
 1 file changed, 30 insertions(+), 11 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index a4a3da6804..531bc74231 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2664,21 +2664,40 @@ static void reachable_code_pass(TCGContext *s)
                 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])) {
+                TCGOp *op_prev = QTAILQ_PREV(op, link);
+                if (label->refs == 1 &&
+                    op_prev->opc == INDEX_op_br &&
+                    label == arg_label(op_prev->args[0])) {
+                    /*
+                     * 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.
+                     */
+                    tcg_op_remove(s, op_prev);
+                    remove = true;
+                } else if (op_next->opc == INDEX_op_set_label) {
+                    /*
+                     * The Hexagon frontend can generate empty else-branches 
for
+                     * certain instructions.  If we encounter
+                     *
+                     *   br $L0
+                     *   set_label $L1
+                     *   set_label $L0
+                     *
+                     * where $L0 only has a single reference, remove the branch
+                     * to $L0 and the corresonding label.
+                     */
+                    TCGLabel *next_label = arg_label(op_next->args[0]);
+                    if (next_label->refs == 1 &&
+                        op_prev->opc == INDEX_op_br &&
+                        next_label == arg_label(op_prev->args[0])) {
                         tcg_op_remove(s, op_prev);
-                        remove = true;
                     }
                 }
             }
+
             break;

         case INDEX_op_br:
--
2.39.1



reply via email to

[Prev in Thread] Current Thread [Next in Thread]