History

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.

Michael Matz committed 10 years ago

Commit ca435dc1 parent 31c7ea02 files · +68 −2Browse files

Unified · Split

2 files
  1. tccgen.c +17 −2
  2. tests/tcctest.c +51 −0
tccgen.c+17−2
@@ -5396,7 +5396,8 @@ static void block(int *bsym, int *csym, int is_expr) · 5395 unmodified lines
5396 nocode_wanted |= 2;5396 nocode_wanted |= 2;
5397 a = gvtst(1, 0);5397 a = gvtst(1, 0);
5398 block(bsym, csym, 0);5398 block(bsym, csym, 0);
5399 nocode_wanted = saved_nocode_wanted;5399 if (cond != 1)
5400 nocode_wanted = saved_nocode_wanted;
5400 c = tok;5401 c = tok;
5401 if (c == TOK_ELSE) {5402 if (c == TOK_ELSE) {
5402 next();5403 next();
@@ -5406,10 +5407,12 @@ static void block(int *bsym, int *csym, int is_expr) · 3 unmodified lines
5406 gsym(a);5407 gsym(a);
5407 block(bsym, csym, 0);5408 block(bsym, csym, 0);
5408 gsym(d); /* patch else jmp */5409 gsym(d); /* patch else jmp */
5409 nocode_wanted = saved_nocode_wanted;5410 if (cond != 0)
5411 nocode_wanted = saved_nocode_wanted;
5410 } else5412 } else
5411 gsym(a);5413 gsym(a);
5412 } else if (tok == TOK_WHILE) {5414 } else if (tok == TOK_WHILE) {
5415 int saved_nocode_wanted;
5413 nocode_wanted &= ~2;5416 nocode_wanted &= ~2;
5414 next();5417 next();
5415 d = ind;5418 d = ind;
@@ -5420,7 +5423,9 @@ static void block(int *bsym, int *csym, int is_expr) · 4 unmodified lines
5420 a = gvtst(1, 0);5423 a = gvtst(1, 0);
5421 b = 0;5424 b = 0;
5422 ++local_scope;5425 ++local_scope;
5426 saved_nocode_wanted = nocode_wanted;
5423 block(&a, &b, 0);5427 block(&a, &b, 0);
5428 nocode_wanted = saved_nocode_wanted;
5424 --local_scope;5429 --local_scope;
5425 if(!nocode_wanted)5430 if(!nocode_wanted)
5426 gjmp_addr(d);5431 gjmp_addr(d);
@@ -5556,6 +5561,7 @@ static void block(int *bsym, int *csym, int is_expr) · 129 unmodified lines
5556 /* jump unless last stmt in top-level block */5561 /* jump unless last stmt in top-level block */
5557 if (tok != '}' || local_scope != 1)5562 if (tok != '}' || local_scope != 1)
5558 rsym = gjmp(rsym);5563 rsym = gjmp(rsym);
5564 nocode_wanted |= 2;
5559 } else if (tok == TOK_BREAK) {5565 } else if (tok == TOK_BREAK) {
5560 /* compute jump */5566 /* compute jump */
5561 if (!bsym)5567 if (!bsym)
@@ -5563,6 +5569,7 @@ static void block(int *bsym, int *csym, int is_expr) · 1 unmodified line
5563 *bsym = gjmp(*bsym);5569 *bsym = gjmp(*bsym);
5564 next();5570 next();
5565 skip(';');5571 skip(';');
5572 nocode_wanted |= 2;
5566 } else if (tok == TOK_CONTINUE) {5573 } else if (tok == TOK_CONTINUE) {
5567 /* compute jump */5574 /* compute jump */
5568 if (!csym)5575 if (!csym)
@@ -5573,6 +5580,7 @@ static void block(int *bsym, int *csym, int is_expr) · 4 unmodified lines
5573 skip(';');5580 skip(';');
5574 } else if (tok == TOK_FOR) {5581 } else if (tok == TOK_FOR) {
5575 int e;5582 int e;
5583 int saved_nocode_wanted;
5576 nocode_wanted &= ~2;5584 nocode_wanted &= ~2;
5577 next();5585 next();
5578 skip('(');5586 skip('(');
@@ -5607,7 +5615,9 @@ static void block(int *bsym, int *csym, int is_expr) · 28 unmodified lines
5607 gsym(e);5615 gsym(e);
5608 }5616 }
5609 skip(')');5617 skip(')');
5618 saved_nocode_wanted = nocode_wanted;
5610 block(&a, &b, 0);5619 block(&a, &b, 0);
5620 nocode_wanted = saved_nocode_wanted;
5611 if(!nocode_wanted)5621 if(!nocode_wanted)
5612 gjmp_addr(c);5622 gjmp_addr(c);
5613 gsym(a);5623 gsym(a);
@@ -5617,13 +5627,16 @@ static void block(int *bsym, int *csym, int is_expr) · 3 unmodified lines
5617 5627
5618 } else 5628 } else
5619 if (tok == TOK_DO) {5629 if (tok == TOK_DO) {
5630 int saved_nocode_wanted;
5620 nocode_wanted &= ~2;5631 nocode_wanted &= ~2;
5621 next();5632 next();
5622 a = 0;5633 a = 0;
5623 b = 0;5634 b = 0;
5624 d = ind;5635 d = ind;
5625 vla_sp_restore();5636 vla_sp_restore();
5637 saved_nocode_wanted = nocode_wanted;
5626 block(&a, &b, 0);5638 block(&a, &b, 0);
5639 nocode_wanted = saved_nocode_wanted;
5627 skip(TOK_WHILE);5640 skip(TOK_WHILE);
5628 skip('(');5641 skip('(');
5629 gsym(b);5642 gsym(b);
@@ -5637,6 +5650,7 @@ static void block(int *bsym, int *csym, int is_expr) · 7 unmodified lines
5637 } else5650 } else
5638 if (tok == TOK_SWITCH) {5651 if (tok == TOK_SWITCH) {
5639 struct switch_t *saved, sw;5652 struct switch_t *saved, sw;
5653 int saved_nocode_wanted = nocode_wanted;
5640 next();5654 next();
5641 skip('(');5655 skip('(');
5642 gexpr();5656 gexpr();
@@ -5650,6 +5664,7 @@ static void block(int *bsym, int *csym, int is_expr) · 7 unmodified lines
5650 saved = cur_switch;5664 saved = cur_switch;
5651 cur_switch = &sw;5665 cur_switch = &sw;
5652 block(&a, csym, 0);5666 block(&a, csym, 0);
5667 nocode_wanted = saved_nocode_wanted;
5653 a = gjmp(a); /* add implicit break */5668 a = gjmp(a); /* add implicit break */
5654 /* case lookup */5669 /* case lookup */
5655 gsym(b);5670 gsym(b);
tests/tcctest.c+51−0
@@ -1184,6 +1184,57 @@ void optimize_out(void) · 1183 unmodified lines
1184 printf("oo:%d\n", defined_function());1184 printf("oo:%d\n", defined_function());
1185 else1185 else
1186 printf("oo:%d\n", undefined_function());1186 printf("oo:%d\n", undefined_function());
1187 while (1) {
1188 printf("oow:%d\n", defined_function());
1189 break;
1190 printf("oow:%d\n", undefined_function());
1191 }
1192 j = 1;
1193 /* Following is a switch without {} block intentionally. */
1194 switch (j)
1195 case 1: break;
1196 printf ("oos:%d\n", defined_function());
1197 /* The following break shouldn't lead to disabled code after
1198 the while. */
1199 while (1)
1200 break;
1201 printf ("ool1:%d\n", defined_function());
1202 /* Same for the other types of loops. */
1203 do
1204 break;
1205 while (1);
1206 printf ("ool2:%d\n", defined_function());
1207 for (;;)
1208 break;
1209 printf ("ool3:%d\n", defined_function());
1210 /* Normal {} blocks without controlling statements
1211 shouldn't reactivate code emission */
1212 while (1) {
1213 {
1214 break;
1215 }
1216 printf ("ool4:%d\n", undefined_function());
1217 }
1218 j = 1;
1219 while (j) {
1220 if (j == 0)
1221 break; /* this break shouldn't disable code outside the if. */
1222 printf("ool5:%d\n", defined_function());
1223 j--;
1224 }
1225
1226 j = 1;
1227 while (j) {
1228 if (1)
1229 j--;
1230 else
1231 breakhere: break;
1232 printf("ool6:%d\n", defined_function());
1233 goto breakhere;
1234 }
1235 if (1)
1236 return;
1237 printf ("oor:%d\n", undefined_function());
1187}1238}
1188 1239
1189int defined_function(void)1240int defined_function(void)

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