/* 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) {
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
/* 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;