diff options
| author | Michael Matz <matz@suse.de> | 2016-09-19 18:38:12 +0200 |
|---|---|---|
| committer | Michael Matz <matz@suse.de> | 2016-12-15 17:47:12 +0100 |
| commit | 31c7ea0165882eaf09040ea7edfc37cc38f0a032 (patch) | |
| tree | d1dad07537700b756d612c68b414d243202a9529 /tccgen.c | |
| parent | b303a00ce01876dfa2ba3fe532db04d200168b9d (diff) | |
| download | tinycc-31c7ea0165882eaf09040ea7edfc37cc38f0a032.tar.gz tinycc-31c7ea0165882eaf09040ea7edfc37cc38f0a032.tar.bz2 | |
opt: Start optimizing dead code a bit
If a condition is always zero/non-zero we can omit the
then or else code. This is complicated a bit by having to
deal with labels that might make such code reachable without
us yet knowing during parsing.
Diffstat (limited to 'tccgen.c')
| -rw-r--r-- | tccgen.c | 17 |
1 files changed, 15 insertions, 2 deletions
@@ -5367,7 +5367,7 @@ static int gcase(struct case_t **base, int len, int case_reg, int *bsym) static void block(int *bsym, int *csym, int is_expr) { - int a, b, c, d; + int a, b, c, d, cond; Sym *s; /* generate line number info */ @@ -5386,22 +5386,31 @@ static void block(int *bsym, int *csym, int is_expr) if (tok == TOK_IF) { /* if test */ + int saved_nocode_wanted = nocode_wanted; next(); skip('('); gexpr(); skip(')'); - a = gvtst(1, 0); + cond = condition_3way(); + if (cond == 0) + nocode_wanted |= 2; + a = gvtst(1, 0); block(bsym, csym, 0); + nocode_wanted = saved_nocode_wanted; c = tok; if (c == TOK_ELSE) { next(); + if (cond == 1) + nocode_wanted |= 2; d = gjmp(0); gsym(a); block(bsym, csym, 0); gsym(d); /* patch else jmp */ + nocode_wanted = saved_nocode_wanted; } else gsym(a); } else if (tok == TOK_WHILE) { + nocode_wanted &= ~2; next(); d = ind; vla_sp_restore(); @@ -5564,6 +5573,7 @@ static void block(int *bsym, int *csym, int is_expr) skip(';'); } else if (tok == TOK_FOR) { int e; + nocode_wanted &= ~2; next(); skip('('); s = local_stack; @@ -5607,6 +5617,7 @@ static void block(int *bsym, int *csym, int is_expr) } else if (tok == TOK_DO) { + nocode_wanted &= ~2; next(); a = 0; b = 0; @@ -5658,6 +5669,7 @@ static void block(int *bsym, int *csym, int is_expr) struct case_t *cr = tcc_malloc(sizeof(struct case_t)); if (!cur_switch) expect("switch"); + nocode_wanted &= ~2; next(); cr->v1 = cr->v2 = expr_const(); if (gnu_ext && tok == TOK_DOTS) { @@ -5735,6 +5747,7 @@ static void block(int *bsym, int *csym, int is_expr) vla_sp_restore(); /* we accept this, but it is a mistake */ block_after_label: + nocode_wanted &= ~2; if (tok == '}') { tcc_warning("deprecated use of label at end of compound statement"); } else { |
