forked from Mirrors/tinycc
opt: constprop also 'cond && 0'
We didn't handle constants in logical expressions when they weren't the first operand. Some reordering in the loop structure is enough to handle them.master
parent
ca435dc2e3
commit
fb933ae0eb
136
tccgen.c
136
tccgen.c
|
@ -4909,37 +4909,43 @@ static void expr_land(void)
|
||||||
{
|
{
|
||||||
expr_or();
|
expr_or();
|
||||||
if (tok == TOK_LAND) {
|
if (tok == TOK_LAND) {
|
||||||
if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
|
int t = 0;
|
||||||
CType ctb, cti;
|
for(;;) {
|
||||||
ctb.t = VT_BOOL;
|
if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
|
||||||
cti.t = VT_INT;
|
CType ctb;
|
||||||
next();
|
ctb.t = VT_BOOL;
|
||||||
gen_cast(&ctb);
|
gen_cast(&ctb);
|
||||||
if (vtop->c.i) {
|
if (vtop->c.i) {
|
||||||
vpop();
|
vpop();
|
||||||
expr_land();
|
} else {
|
||||||
gen_cast(&ctb);
|
int saved_nocode_wanted = nocode_wanted;
|
||||||
} else {
|
nocode_wanted = 1;
|
||||||
int saved_nocode_wanted = nocode_wanted;
|
while (tok == TOK_LAND) {
|
||||||
nocode_wanted = 1;
|
next();
|
||||||
expr_land();
|
expr_or();
|
||||||
vpop();
|
vpop();
|
||||||
nocode_wanted = saved_nocode_wanted;
|
}
|
||||||
}
|
if (t)
|
||||||
gen_cast(&cti);
|
gsym(t);
|
||||||
} else {
|
nocode_wanted = saved_nocode_wanted;
|
||||||
int t = 0;
|
gen_cast(&int_type);
|
||||||
save_regs(1);
|
break;
|
||||||
for(;;) {
|
}
|
||||||
t = gvtst(1, t);
|
} else {
|
||||||
if (tok != TOK_LAND) {
|
if (!t)
|
||||||
vseti(VT_JMPI, t);
|
save_regs(1);
|
||||||
break;
|
t = gvtst(1, t);
|
||||||
}
|
}
|
||||||
next();
|
if (tok != TOK_LAND) {
|
||||||
expr_or();
|
if (t)
|
||||||
}
|
vseti(VT_JMPI, t);
|
||||||
}
|
else
|
||||||
|
vpushi(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
expr_or();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4947,37 +4953,43 @@ static void expr_lor(void)
|
||||||
{
|
{
|
||||||
expr_land();
|
expr_land();
|
||||||
if (tok == TOK_LOR) {
|
if (tok == TOK_LOR) {
|
||||||
if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
|
int t = 0;
|
||||||
CType ctb, cti;
|
for(;;) {
|
||||||
ctb.t = VT_BOOL;
|
if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
|
||||||
cti.t = VT_INT;
|
CType ctb;
|
||||||
next();
|
ctb.t = VT_BOOL;
|
||||||
gen_cast(&ctb);
|
gen_cast(&ctb);
|
||||||
if (vtop->c.i) {
|
if (!vtop->c.i) {
|
||||||
int saved_nocode_wanted = nocode_wanted;
|
vpop();
|
||||||
nocode_wanted = 1;
|
} else {
|
||||||
expr_lor();
|
int saved_nocode_wanted = nocode_wanted;
|
||||||
vpop();
|
nocode_wanted = 1;
|
||||||
nocode_wanted = saved_nocode_wanted;
|
while (tok == TOK_LOR) {
|
||||||
} else {
|
next();
|
||||||
vpop();
|
expr_land();
|
||||||
expr_lor();
|
vpop();
|
||||||
gen_cast(&ctb);
|
}
|
||||||
}
|
if (t)
|
||||||
gen_cast(&cti);
|
gsym(t);
|
||||||
} else {
|
nocode_wanted = saved_nocode_wanted;
|
||||||
int t = 0;
|
gen_cast(&int_type);
|
||||||
save_regs(1);
|
break;
|
||||||
for(;;) {
|
}
|
||||||
t = gvtst(0, t);
|
} else {
|
||||||
if (tok != TOK_LOR) {
|
if (!t)
|
||||||
vseti(VT_JMP, t);
|
save_regs(1);
|
||||||
break;
|
t = gvtst(0, t);
|
||||||
}
|
}
|
||||||
next();
|
if (tok != TOK_LOR) {
|
||||||
expr_land();
|
if (t)
|
||||||
}
|
vseti(VT_JMP, t);
|
||||||
}
|
else
|
||||||
|
vpushi(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
expr_land();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1232,6 +1232,38 @@ void optimize_out(void)
|
||||||
printf("ool6:%d\n", defined_function());
|
printf("ool6:%d\n", defined_function());
|
||||||
goto breakhere;
|
goto breakhere;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Test that constants in logical && are optimized: */
|
||||||
|
i = 0 && undefined_function();
|
||||||
|
i = defined_function() && 0 && undefined_function();
|
||||||
|
if (0 && undefined_function())
|
||||||
|
undefined_function();
|
||||||
|
if (defined_function() && 0)
|
||||||
|
undefined_function();
|
||||||
|
if (0 && 0)
|
||||||
|
undefined_function();
|
||||||
|
if (defined_function() && 0 && undefined_function())
|
||||||
|
undefined_function();
|
||||||
|
/* The same for || : */
|
||||||
|
i = 1 || undefined_function();
|
||||||
|
i = defined_function() || 1 || undefined_function();
|
||||||
|
if (1 || undefined_function())
|
||||||
|
;
|
||||||
|
else
|
||||||
|
undefined_function();
|
||||||
|
if (defined_function() || 1)
|
||||||
|
;
|
||||||
|
else
|
||||||
|
undefined_function();
|
||||||
|
if (1 || 1)
|
||||||
|
;
|
||||||
|
else
|
||||||
|
undefined_function();
|
||||||
|
if (defined_function() || 1 || undefined_function())
|
||||||
|
;
|
||||||
|
else
|
||||||
|
undefined_function();
|
||||||
|
|
||||||
if (1)
|
if (1)
|
||||||
return;
|
return;
|
||||||
printf ("oor:%d\n", undefined_function());
|
printf ("oor:%d\n", undefined_function());
|
||||||
|
@ -2544,6 +2576,13 @@ void sizeof_test(void)
|
||||||
/* And as direct sizeof argument (as unary expression): */
|
/* And as direct sizeof argument (as unary expression): */
|
||||||
printf("sizeof (struct {short i; short j;}){4,5} = %d\n",
|
printf("sizeof (struct {short i; short j;}){4,5} = %d\n",
|
||||||
sizeof (struct {short i; short j;}){4,5} );
|
sizeof (struct {short i; short j;}){4,5} );
|
||||||
|
|
||||||
|
/* sizeof(x && y) should be sizeof(int), even if constant
|
||||||
|
evaluating is possible. */
|
||||||
|
printf("sizeof(t && 0) = %d\n", sizeof(t && 0));
|
||||||
|
printf("sizeof(1 && 1) = %d\n", sizeof(1 && 1));
|
||||||
|
printf("sizeof(t || 1) = %d\n", sizeof(t || 1));
|
||||||
|
printf("sizeof(0 || 0) = %d\n", sizeof(0 || 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void typeof_test(void)
|
void typeof_test(void)
|
||||||
|
|
Loading…
Reference in New Issue