From ca435dc2e36c685a225933283841ab3a827c3316 Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Mon, 26 Sep 2016 20:31:24 +0200 Subject: 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. --- tccgen.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'tccgen.c') 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); -- cgit v1.3.1