mirror of
https://github.com/frida/tinycc
synced 2025-01-04 11:04:42 +03:00
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.
This commit is contained in:
parent
31c7ea0165
commit
ca435dc2e3
19
tccgen.c
19
tccgen.c
@ -5396,7 +5396,8 @@ static void block(int *bsym, int *csym, int is_expr)
|
|||||||
nocode_wanted |= 2;
|
nocode_wanted |= 2;
|
||||||
a = gvtst(1, 0);
|
a = gvtst(1, 0);
|
||||||
block(bsym, csym, 0);
|
block(bsym, csym, 0);
|
||||||
nocode_wanted = saved_nocode_wanted;
|
if (cond != 1)
|
||||||
|
nocode_wanted = saved_nocode_wanted;
|
||||||
c = tok;
|
c = tok;
|
||||||
if (c == TOK_ELSE) {
|
if (c == TOK_ELSE) {
|
||||||
next();
|
next();
|
||||||
@ -5406,10 +5407,12 @@ static void block(int *bsym, int *csym, int is_expr)
|
|||||||
gsym(a);
|
gsym(a);
|
||||||
block(bsym, csym, 0);
|
block(bsym, csym, 0);
|
||||||
gsym(d); /* patch else jmp */
|
gsym(d); /* patch else jmp */
|
||||||
nocode_wanted = saved_nocode_wanted;
|
if (cond != 0)
|
||||||
|
nocode_wanted = saved_nocode_wanted;
|
||||||
} else
|
} else
|
||||||
gsym(a);
|
gsym(a);
|
||||||
} else if (tok == TOK_WHILE) {
|
} else if (tok == TOK_WHILE) {
|
||||||
|
int saved_nocode_wanted;
|
||||||
nocode_wanted &= ~2;
|
nocode_wanted &= ~2;
|
||||||
next();
|
next();
|
||||||
d = ind;
|
d = ind;
|
||||||
@ -5420,7 +5423,9 @@ static void block(int *bsym, int *csym, int is_expr)
|
|||||||
a = gvtst(1, 0);
|
a = gvtst(1, 0);
|
||||||
b = 0;
|
b = 0;
|
||||||
++local_scope;
|
++local_scope;
|
||||||
|
saved_nocode_wanted = nocode_wanted;
|
||||||
block(&a, &b, 0);
|
block(&a, &b, 0);
|
||||||
|
nocode_wanted = saved_nocode_wanted;
|
||||||
--local_scope;
|
--local_scope;
|
||||||
if(!nocode_wanted)
|
if(!nocode_wanted)
|
||||||
gjmp_addr(d);
|
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 */
|
/* jump unless last stmt in top-level block */
|
||||||
if (tok != '}' || local_scope != 1)
|
if (tok != '}' || local_scope != 1)
|
||||||
rsym = gjmp(rsym);
|
rsym = gjmp(rsym);
|
||||||
|
nocode_wanted |= 2;
|
||||||
} else if (tok == TOK_BREAK) {
|
} else if (tok == TOK_BREAK) {
|
||||||
/* compute jump */
|
/* compute jump */
|
||||||
if (!bsym)
|
if (!bsym)
|
||||||
@ -5563,6 +5569,7 @@ static void block(int *bsym, int *csym, int is_expr)
|
|||||||
*bsym = gjmp(*bsym);
|
*bsym = gjmp(*bsym);
|
||||||
next();
|
next();
|
||||||
skip(';');
|
skip(';');
|
||||||
|
nocode_wanted |= 2;
|
||||||
} else if (tok == TOK_CONTINUE) {
|
} else if (tok == TOK_CONTINUE) {
|
||||||
/* compute jump */
|
/* compute jump */
|
||||||
if (!csym)
|
if (!csym)
|
||||||
@ -5573,6 +5580,7 @@ static void block(int *bsym, int *csym, int is_expr)
|
|||||||
skip(';');
|
skip(';');
|
||||||
} else if (tok == TOK_FOR) {
|
} else if (tok == TOK_FOR) {
|
||||||
int e;
|
int e;
|
||||||
|
int saved_nocode_wanted;
|
||||||
nocode_wanted &= ~2;
|
nocode_wanted &= ~2;
|
||||||
next();
|
next();
|
||||||
skip('(');
|
skip('(');
|
||||||
@ -5607,7 +5615,9 @@ static void block(int *bsym, int *csym, int is_expr)
|
|||||||
gsym(e);
|
gsym(e);
|
||||||
}
|
}
|
||||||
skip(')');
|
skip(')');
|
||||||
|
saved_nocode_wanted = nocode_wanted;
|
||||||
block(&a, &b, 0);
|
block(&a, &b, 0);
|
||||||
|
nocode_wanted = saved_nocode_wanted;
|
||||||
if(!nocode_wanted)
|
if(!nocode_wanted)
|
||||||
gjmp_addr(c);
|
gjmp_addr(c);
|
||||||
gsym(a);
|
gsym(a);
|
||||||
@ -5617,13 +5627,16 @@ static void block(int *bsym, int *csym, int is_expr)
|
|||||||
|
|
||||||
} else
|
} else
|
||||||
if (tok == TOK_DO) {
|
if (tok == TOK_DO) {
|
||||||
|
int saved_nocode_wanted;
|
||||||
nocode_wanted &= ~2;
|
nocode_wanted &= ~2;
|
||||||
next();
|
next();
|
||||||
a = 0;
|
a = 0;
|
||||||
b = 0;
|
b = 0;
|
||||||
d = ind;
|
d = ind;
|
||||||
vla_sp_restore();
|
vla_sp_restore();
|
||||||
|
saved_nocode_wanted = nocode_wanted;
|
||||||
block(&a, &b, 0);
|
block(&a, &b, 0);
|
||||||
|
nocode_wanted = saved_nocode_wanted;
|
||||||
skip(TOK_WHILE);
|
skip(TOK_WHILE);
|
||||||
skip('(');
|
skip('(');
|
||||||
gsym(b);
|
gsym(b);
|
||||||
@ -5637,6 +5650,7 @@ static void block(int *bsym, int *csym, int is_expr)
|
|||||||
} else
|
} else
|
||||||
if (tok == TOK_SWITCH) {
|
if (tok == TOK_SWITCH) {
|
||||||
struct switch_t *saved, sw;
|
struct switch_t *saved, sw;
|
||||||
|
int saved_nocode_wanted = nocode_wanted;
|
||||||
next();
|
next();
|
||||||
skip('(');
|
skip('(');
|
||||||
gexpr();
|
gexpr();
|
||||||
@ -5650,6 +5664,7 @@ static void block(int *bsym, int *csym, int is_expr)
|
|||||||
saved = cur_switch;
|
saved = cur_switch;
|
||||||
cur_switch = &sw;
|
cur_switch = &sw;
|
||||||
block(&a, csym, 0);
|
block(&a, csym, 0);
|
||||||
|
nocode_wanted = saved_nocode_wanted;
|
||||||
a = gjmp(a); /* add implicit break */
|
a = gjmp(a); /* add implicit break */
|
||||||
/* case lookup */
|
/* case lookup */
|
||||||
gsym(b);
|
gsym(b);
|
||||||
|
@ -1184,6 +1184,57 @@ void optimize_out(void)
|
|||||||
printf("oo:%d\n", defined_function());
|
printf("oo:%d\n", defined_function());
|
||||||
else
|
else
|
||||||
printf("oo:%d\n", undefined_function());
|
printf("oo:%d\n", undefined_function());
|
||||||
|
while (1) {
|
||||||
|
printf("oow:%d\n", defined_function());
|
||||||
|
break;
|
||||||
|
printf("oow:%d\n", undefined_function());
|
||||||
|
}
|
||||||
|
j = 1;
|
||||||
|
/* Following is a switch without {} block intentionally. */
|
||||||
|
switch (j)
|
||||||
|
case 1: break;
|
||||||
|
printf ("oos:%d\n", defined_function());
|
||||||
|
/* The following break shouldn't lead to disabled code after
|
||||||
|
the while. */
|
||||||
|
while (1)
|
||||||
|
break;
|
||||||
|
printf ("ool1:%d\n", defined_function());
|
||||||
|
/* Same for the other types of loops. */
|
||||||
|
do
|
||||||
|
break;
|
||||||
|
while (1);
|
||||||
|
printf ("ool2:%d\n", defined_function());
|
||||||
|
for (;;)
|
||||||
|
break;
|
||||||
|
printf ("ool3:%d\n", defined_function());
|
||||||
|
/* Normal {} blocks without controlling statements
|
||||||
|
shouldn't reactivate code emission */
|
||||||
|
while (1) {
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printf ("ool4:%d\n", undefined_function());
|
||||||
|
}
|
||||||
|
j = 1;
|
||||||
|
while (j) {
|
||||||
|
if (j == 0)
|
||||||
|
break; /* this break shouldn't disable code outside the if. */
|
||||||
|
printf("ool5:%d\n", defined_function());
|
||||||
|
j--;
|
||||||
|
}
|
||||||
|
|
||||||
|
j = 1;
|
||||||
|
while (j) {
|
||||||
|
if (1)
|
||||||
|
j--;
|
||||||
|
else
|
||||||
|
breakhere: break;
|
||||||
|
printf("ool6:%d\n", defined_function());
|
||||||
|
goto breakhere;
|
||||||
|
}
|
||||||
|
if (1)
|
||||||
|
return;
|
||||||
|
printf ("oor:%d\n", undefined_function());
|
||||||
}
|
}
|
||||||
|
|
||||||
int defined_function(void)
|
int defined_function(void)
|
||||||
|
Loading…
Reference in New Issue
Block a user