aboutsummaryrefslogtreecommitdiff
path: root/tccgen.c
diff options
context:
space:
mode:
authorMichael Matz <matz@suse.de>2016-09-26 20:31:24 +0200
committerMichael Matz <matz@suse.de>2016-12-15 17:47:12 +0100
commitca435dc2e36c685a225933283841ab3a827c3316 (patch)
tree880c2179942504895e7b21971fa68c36f064e57a /tccgen.c
parent31c7ea0165882eaf09040ea7edfc37cc38f0a032 (diff)
downloadtinycc-ca435dc2e36c685a225933283841ab3a827c3316.tar.gz
tinycc-ca435dc2e36c685a225933283841ab3a827c3316.tar.bz2
opt: Make break and goto not fallthrough
As we can optimize dead code a bit already it's fitting to disable code emission after break and goto.
Diffstat (limited to 'tccgen.c')
-rw-r--r--tccgen.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/tccgen.c b/tccgen.c
index 8b1bcb1..c9d43b4 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -5396,7 +5396,8 @@ static void block(int *bsym, int *csym, int is_expr)
nocode_wanted |= 2;
a = gvtst(1, 0);
block(bsym, csym, 0);
- nocode_wanted = saved_nocode_wanted;
+ if (cond != 1)
+ nocode_wanted = saved_nocode_wanted;
c = tok;
if (c == TOK_ELSE) {
next();
@@ -5406,10 +5407,12 @@ static void block(int *bsym, int *csym, int is_expr)
gsym(a);
block(bsym, csym, 0);
gsym(d); /* patch else jmp */
- nocode_wanted = saved_nocode_wanted;
+ if (cond != 0)
+ nocode_wanted = saved_nocode_wanted;
} else
gsym(a);
} else if (tok == TOK_WHILE) {
+ int saved_nocode_wanted;
nocode_wanted &= ~2;
next();
d = ind;
@@ -5420,7 +5423,9 @@ static void block(int *bsym, int *csym, int is_expr)
a = gvtst(1, 0);
b = 0;
++local_scope;
+ saved_nocode_wanted = nocode_wanted;
block(&a, &b, 0);
+ nocode_wanted = saved_nocode_wanted;
--local_scope;
if(!nocode_wanted)
gjmp_addr(d);
@@ -5556,6 +5561,7 @@ static void block(int *bsym, int *csym, int is_expr)
/* jump unless last stmt in top-level block */
if (tok != '}' || local_scope != 1)
rsym = gjmp(rsym);
+ nocode_wanted |= 2;
} else if (tok == TOK_BREAK) {
/* compute jump */
if (!bsym)
@@ -5563,6 +5569,7 @@ static void block(int *bsym, int *csym, int is_expr)
*bsym = gjmp(*bsym);
next();
skip(';');
+ nocode_wanted |= 2;
} else if (tok == TOK_CONTINUE) {
/* compute jump */
if (!csym)
@@ -5573,6 +5580,7 @@ static void block(int *bsym, int *csym, int is_expr)
skip(';');
} else if (tok == TOK_FOR) {
int e;
+ int saved_nocode_wanted;
nocode_wanted &= ~2;
next();
skip('(');
@@ -5607,7 +5615,9 @@ static void block(int *bsym, int *csym, int is_expr)
gsym(e);
}
skip(')');
+ saved_nocode_wanted = nocode_wanted;
block(&a, &b, 0);
+ nocode_wanted = saved_nocode_wanted;
if(!nocode_wanted)
gjmp_addr(c);
gsym(a);
@@ -5617,13 +5627,16 @@ static void block(int *bsym, int *csym, int is_expr)
} else
if (tok == TOK_DO) {
+ int saved_nocode_wanted;
nocode_wanted &= ~2;
next();
a = 0;
b = 0;
d = ind;
vla_sp_restore();
+ saved_nocode_wanted = nocode_wanted;
block(&a, &b, 0);
+ nocode_wanted = saved_nocode_wanted;
skip(TOK_WHILE);
skip('(');
gsym(b);
@@ -5637,6 +5650,7 @@ static void block(int *bsym, int *csym, int is_expr)
} else
if (tok == TOK_SWITCH) {
struct switch_t *saved, sw;
+ int saved_nocode_wanted = nocode_wanted;
next();
skip('(');
gexpr();
@@ -5650,6 +5664,7 @@ static void block(int *bsym, int *csym, int is_expr)
saved = cur_switch;
cur_switch = &sw;
block(&a, csym, 0);
+ nocode_wanted = saved_nocode_wanted;
a = gjmp(a); /* add implicit break */
/* case lookup */
gsym(b);