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
53965396 nocode_wanted |= 2;
53975397 a = gvtst(1, 0);
53985398 block(bsym, csym, 0);
5399− nocode_wanted = saved_nocode_wanted;
5399+ if (cond != 1)
5400+ nocode_wanted = saved_nocode_wanted;
54005401 c = tok;
54015402 if (c == TOK_ELSE) {
54025403 next();
@@ -5406,10 +5407,12 @@ static void block(int *bsym, int *csym, int is_expr) · 3 unmodified lines
54065407 gsym(a);
54075408 block(bsym, csym, 0);
54085409 gsym(d); /* patch else jmp */
5409− nocode_wanted = saved_nocode_wanted;
5410+ if (cond != 0)
5411+ nocode_wanted = saved_nocode_wanted;
54105412 } else
54115413 gsym(a);
54125414 } else if (tok == TOK_WHILE) {
5415+ int saved_nocode_wanted;
54135416 nocode_wanted &= ~2;
54145417 next();
54155418 d = ind;
@@ -5420,7 +5423,9 @@ static void block(int *bsym, int *csym, int is_expr) · 4 unmodified lines
54205423 a = gvtst(1, 0);
54215424 b = 0;
54225425 ++local_scope;
5426+ saved_nocode_wanted = nocode_wanted;
54235427 block(&a, &b, 0);
5428+ nocode_wanted = saved_nocode_wanted;
54245429 --local_scope;
54255430 if(!nocode_wanted)
54265431 gjmp_addr(d);
@@ -5556,6 +5561,7 @@ static void block(int *bsym, int *csym, int is_expr) · 129 unmodified lines
55565561 /* jump unless last stmt in top-level block */
55575562 if (tok != '}' || local_scope != 1)
55585563 rsym = gjmp(rsym);
5564+ nocode_wanted |= 2;
55595565 } else if (tok == TOK_BREAK) {
55605566 /* compute jump */
55615567 if (!bsym)
@@ -5563,6 +5569,7 @@ static void block(int *bsym, int *csym, int is_expr) · 1 unmodified line
55635569 *bsym = gjmp(*bsym);
55645570 next();
55655571 skip(';');
5572+ nocode_wanted |= 2;
55665573 } else if (tok == TOK_CONTINUE) {
55675574 /* compute jump */
55685575 if (!csym)
@@ -5573,6 +5580,7 @@ static void block(int *bsym, int *csym, int is_expr) · 4 unmodified lines
55735580 skip(';');
55745581 } else if (tok == TOK_FOR) {
55755582 int e;
5583+ int saved_nocode_wanted;
55765584 nocode_wanted &= ~2;
55775585 next();
55785586 skip('(');
@@ -5607,7 +5615,9 @@ static void block(int *bsym, int *csym, int is_expr) · 28 unmodified lines
56075615 gsym(e);
56085616 }
56095617 skip(')');
5618+ saved_nocode_wanted = nocode_wanted;
56105619 block(&a, &b, 0);
5620+ nocode_wanted = saved_nocode_wanted;
56115621 if(!nocode_wanted)
56125622 gjmp_addr(c);
56135623 gsym(a);
@@ -5617,13 +5627,16 @@ static void block(int *bsym, int *csym, int is_expr) · 3 unmodified lines
56175627
56185628 } else
56195629 if (tok == TOK_DO) {
5630+ int saved_nocode_wanted;
56205631 nocode_wanted &= ~2;
56215632 next();
56225633 a = 0;
56235634 b = 0;
56245635 d = ind;
56255636 vla_sp_restore();
5637+ saved_nocode_wanted = nocode_wanted;
56265638 block(&a, &b, 0);
5639+ nocode_wanted = saved_nocode_wanted;
56275640 skip(TOK_WHILE);
56285641 skip('(');
56295642 gsym(b);
@@ -5637,6 +5650,7 @@ static void block(int *bsym, int *csym, int is_expr) · 7 unmodified lines
56375650 } else
56385651 if (tok == TOK_SWITCH) {
56395652 struct switch_t *saved, sw;
5653+ int saved_nocode_wanted = nocode_wanted;
56405654 next();
56415655 skip('(');
56425656 gexpr();
@@ -5650,6 +5664,7 @@ static void block(int *bsym, int *csym, int is_expr) · 7 unmodified lines
56505664 saved = cur_switch;
56515665 cur_switch = &sw;
56525666 block(&a, csym, 0);
5667+ nocode_wanted = saved_nocode_wanted;
56535668 a = gjmp(a); /* add implicit break */
56545669 /* case lookup */
56555670 gsym(b);
tests/tcctest.c+51−0
@@ -1184,6 +1184,57 @@ void optimize_out(void) · 1183 unmodified lines
11841184 printf("oo:%d\n", defined_function());
11851185 else
11861186 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());
11871238 }
11881239
11891240 int 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