dce: Don't force unreachable case label to be live

if a switch is unreachable then so are the case labels.
Unlike normal labels they can't possibly be reached from not-yet
parsed code, so there's no reason to enable codegen again for those.
This commit is contained in:
Michael Matz 2022-07-12 17:07:33 +02:00
parent 0c36b3ff2d
commit c3e3a07ed4
2 changed files with 25 additions and 8 deletions

View file

@ -62,7 +62,15 @@ ST_DATA int nocode_wanted; /* no code generation wanted */
/* Clear 'nocode_wanted' at label if it was used */
ST_FUNC void gsym(int t) { if (t) { gsym_addr(t, ind); CODE_ON(); }}
static int gind(void) { int t = ind; CODE_ON(); if (debug_modes) tcc_tcov_block_begin(tcc_state); return t; }
static int gind(int known_unreachable)
{
int t = ind;
if (!known_unreachable)
CODE_ON();
if (debug_modes)
tcc_tcov_block_begin(tcc_state);
return t;
}
/* Set 'nocode_wanted' after unconditional jumps */
static void gjmp_addr_acs(int t) { gjmp_addr(t); CODE_OFF(); }
@ -99,6 +107,7 @@ static struct switch_t {
int sym;
} **p; int n; /* list of case ranges */
int def_sym; /* default symbol */
int nocode_wanted;
int *bsym;
struct scope *scope;
struct switch_t *prev;
@ -6769,7 +6778,7 @@ again:
}
} else if (t == TOK_WHILE) {
d = gind();
d = gind(0);
skip('(');
gexpr();
skip(')');
@ -6869,7 +6878,7 @@ again:
}
skip(';');
a = b = 0;
c = d = gind();
c = d = gind(0);
if (tok != ';') {
gexpr();
a = gvtst(1, 0);
@ -6877,7 +6886,7 @@ again:
skip(';');
if (tok != ')') {
e = gjmp(0);
d = gind();
d = gind(0);
gexpr();
vpop();
gjmp_addr(c);
@ -6892,7 +6901,7 @@ again:
} else if (t == TOK_DO) {
a = b = 0;
d = gind();
d = gind(0);
lblock(&a, &b);
gsym(b);
skip(TOK_WHILE);
@ -6911,6 +6920,7 @@ again:
sw->bsym = &a;
sw->scope = cur_scope;
sw->prev = cur_switch;
sw->nocode_wanted = nocode_wanted;
cur_switch = sw;
skip('(');
@ -6965,7 +6975,7 @@ again:
}
if (debug_modes)
tcc_tcov_reset_ind(tcc_state);
cr->sym = gind();
cr->sym = gind(cur_switch->nocode_wanted);
dynarray_add(&cur_switch->p, &cur_switch->n, cr);
skip(':');
is_expr = 0;
@ -6978,7 +6988,7 @@ again:
tcc_error("too many 'default'");
if (debug_modes)
tcc_tcov_reset_ind(tcc_state);
cur_switch->def_sym = gind();
cur_switch->def_sym = gind(cur_switch->nocode_wanted);
skip(':');
is_expr = 0;
goto block_after_label;
@ -7044,7 +7054,7 @@ again:
} else {
s = label_push(&global_label_stack, t, LABEL_DEFINED);
}
s->jnext = gind();
s->jnext = gind(0);
s->cleanupstate = cur_scope->cl.s;
block_after_label:

View file

@ -1418,6 +1418,13 @@ void optimize_out_test(void)
undefined_function();
}
if (0) {
switch (defined_function()) {
case 0: undefined_function(); break;
default: undefined_function(); break;
}
}
/* Leave the "if(1)return; printf()" in this order and last in the function */
if (1)
return;