History

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.

Michael Matz committed 4 years ago

Commit c3e3a071 parent 0c36b3f2 files · +25 −8Browse files

Unified · Split

2 files
  1. tccgen.c +18 −8
  2. tests/tcctest.c +7 −0
tccgen.c+18−8
@@ -62,7 +62,15 @@ ST_DATA int nocode_wanted; /* no code generation wanted */ · 61 unmodified lines
6262
6363 /* Clear 'nocode_wanted' at label if it was used */
6464 ST_FUNC void gsym(int t) { if (t) { gsym_addr(t, ind); CODE_ON(); }}
65−static int gind(void) { int t = ind; CODE_ON(); if (debug_modes) tcc_tcov_block_begin(tcc_state); return t; }
65+static int gind(int known_unreachable)
66+{
67+ int t = ind;
68+ if (!known_unreachable)
69+ CODE_ON();
70+ if (debug_modes)
71+ tcc_tcov_block_begin(tcc_state);
72+ return t;
73+}
6674
6775 /* Set 'nocode_wanted' after unconditional jumps */
6876 static void gjmp_addr_acs(int t) { gjmp_addr(t); CODE_OFF(); }
@@ -99,6 +107,7 @@ static struct switch_t { · 30 unmodified lines
99107 int sym;
100108 } **p; int n; /* list of case ranges */
101109 int def_sym; /* default symbol */
110+ int nocode_wanted;
102111 int *bsym;
103112 struct scope *scope;
104113 struct switch_t *prev;
@@ -6769,7 +6778,7 @@ again: · 6664 unmodified lines
67696778 }
67706779
67716780 } else if (t == TOK_WHILE) {
6772− d = gind();
6781+ d = gind(0);
67736782 skip('(');
67746783 gexpr();
67756784 skip(')');
@@ -6869,7 +6878,7 @@ again: · 93 unmodified lines
68696878 }
68706879 skip(';');
68716880 a = b = 0;
6872− c = d = gind();
6881+ c = d = gind(0);
68736882 if (tok != ';') {
68746883 gexpr();
68756884 a = gvtst(1, 0);
@@ -6877,7 +6886,7 @@ again: · 1 unmodified line
68776886 skip(';');
68786887 if (tok != ')') {
68796888 e = gjmp(0);
6880− d = gind();
6889+ d = gind(0);
68816890 gexpr();
68826891 vpop();
68836892 gjmp_addr(c);
@@ -6892,7 +6901,7 @@ again: · 8 unmodified lines
68926901
68936902 } else if (t == TOK_DO) {
68946903 a = b = 0;
6895− d = gind();
6904+ d = gind(0);
68966905 lblock(&a, &b);
68976906 gsym(b);
68986907 skip(TOK_WHILE);
@@ -6911,6 +6920,7 @@ again: · 12 unmodified lines
69116920 sw->bsym = &a;
69126921 sw->scope = cur_scope;
69136922 sw->prev = cur_switch;
6923+ sw->nocode_wanted = nocode_wanted;
69146924 cur_switch = sw;
69156925
69166926 skip('(');
@@ -6965,7 +6975,7 @@ again: · 48 unmodified lines
69656975 }
69666976 if (debug_modes)
69676977 tcc_tcov_reset_ind(tcc_state);
6968− cr->sym = gind();
6978+ cr->sym = gind(cur_switch->nocode_wanted);
69696979 dynarray_add(&cur_switch->p, &cur_switch->n, cr);
69706980 skip(':');
69716981 is_expr = 0;
@@ -6978,7 +6988,7 @@ again: · 6 unmodified lines
69786988 tcc_error("too many 'default'");
69796989 if (debug_modes)
69806990 tcc_tcov_reset_ind(tcc_state);
6981− cur_switch->def_sym = gind();
6991+ cur_switch->def_sym = gind(cur_switch->nocode_wanted);
69826992 skip(':');
69836993 is_expr = 0;
69846994 goto block_after_label;
@@ -7044,7 +7054,7 @@ again: · 59 unmodified lines
70447054 } else {
70457055 s = label_push(&global_label_stack, t, LABEL_DEFINED);
70467056 }
7047− s->jnext = gind();
7057+ s->jnext = gind(0);
70487058 s->cleanupstate = cur_scope->cl.s;
70497059
70507060 block_after_label:
tests/tcctest.c+7−0
@@ -1418,6 +1418,13 @@ void optimize_out_test(void) · 1417 unmodified lines
14181418 undefined_function();
14191419 }
14201420
1421+ if (0) {
1422+ switch (defined_function()) {
1423+ case 0: undefined_function(); break;
1424+ default: undefined_function(); break;
1425+ }
1426+ }
1427+
14211428 /* Leave the "if(1)return; printf()" in this order and last in the function */
14221429 if (1)
14231430 return;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t