History

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.

Michael Matz committed 10 years ago

Commit fb933ae1 parent ca435dc2 files · +113 −62Browse files

Unified · Split

2 files
  1. tccgen.c +74 −62
  2. tests/tcctest.c +39 −0
tccgen.c+74−62
@@ -4909,37 +4909,43 @@ static void expr_land(void) · 4908 unmodified lines
49094909 {
49104910 expr_or();
49114911 if (tok == TOK_LAND) {
4912− if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4913− CType ctb, cti;
4914− ctb.t = VT_BOOL;
4915− cti.t = VT_INT;
4916− next();
4917− gen_cast(&ctb);
4918− if (vtop->c.i) {
4919− vpop();
4920− expr_land();
4921− gen_cast(&ctb);
4922− } else {
4923− int saved_nocode_wanted = nocode_wanted;
4924− nocode_wanted = 1;
4925− expr_land();
4926− vpop();
4927− nocode_wanted = saved_nocode_wanted;
4928− }
4929− gen_cast(&cti);
4930− } else {
4931− int t = 0;
4932− save_regs(1);
4933− for(;;) {
4934− t = gvtst(1, t);
4935− if (tok != TOK_LAND) {
4936− vseti(VT_JMPI, t);
4937− break;
4938− }
4939− next();
4940− expr_or();
4941− }
4942− }
4912+ int t = 0;
4913+ for(;;) {
4914+ if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4915+ CType ctb;
4916+ ctb.t = VT_BOOL;
4917+ gen_cast(&ctb);
4918+ if (vtop->c.i) {
4919+ vpop();
4920+ } else {
4921+ int saved_nocode_wanted = nocode_wanted;
4922+ nocode_wanted = 1;
4923+ while (tok == TOK_LAND) {
4924+ next();
4925+ expr_or();
4926+ vpop();
4927+ }
4928+ if (t)
4929+ gsym(t);
4930+ nocode_wanted = saved_nocode_wanted;
4931+ gen_cast(&int_type);
4932+ break;
4933+ }
4934+ } else {
4935+ if (!t)
4936+ save_regs(1);
4937+ t = gvtst(1, t);
4938+ }
4939+ if (tok != TOK_LAND) {
4940+ if (t)
4941+ vseti(VT_JMPI, t);
4942+ else
4943+ vpushi(1);
4944+ break;
4945+ }
4946+ next();
4947+ expr_or();
4948+ }
49434949 }
49444950 }
49454951
@@ -4947,37 +4953,43 @@ static void expr_lor(void) · 1 unmodified line
49474953 {
49484954 expr_land();
49494955 if (tok == TOK_LOR) {
4950− if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4951− CType ctb, cti;
4952− ctb.t = VT_BOOL;
4953− cti.t = VT_INT;
4954− next();
4955− gen_cast(&ctb);
4956− if (vtop->c.i) {
4957− int saved_nocode_wanted = nocode_wanted;
4958− nocode_wanted = 1;
4959− expr_lor();
4960− vpop();
4961− nocode_wanted = saved_nocode_wanted;
4962− } else {
4963− vpop();
4964− expr_lor();
4965− gen_cast(&ctb);
4966− }
4967− gen_cast(&cti);
4968− } else {
4969− int t = 0;
4970− save_regs(1);
4971− for(;;) {
4972− t = gvtst(0, t);
4973− if (tok != TOK_LOR) {
4974− vseti(VT_JMP, t);
4975− break;
4976− }
4977− next();
4978− expr_land();
4979− }
4980− }
4956+ int t = 0;
4957+ for(;;) {
4958+ if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4959+ CType ctb;
4960+ ctb.t = VT_BOOL;
4961+ gen_cast(&ctb);
4962+ if (!vtop->c.i) {
4963+ vpop();
4964+ } else {
4965+ int saved_nocode_wanted = nocode_wanted;
4966+ nocode_wanted = 1;
4967+ while (tok == TOK_LOR) {
4968+ next();
4969+ expr_land();
4970+ vpop();
4971+ }
4972+ if (t)
4973+ gsym(t);
4974+ nocode_wanted = saved_nocode_wanted;
4975+ gen_cast(&int_type);
4976+ break;
4977+ }
4978+ } else {
4979+ if (!t)
4980+ save_regs(1);
4981+ t = gvtst(0, t);
4982+ }
4983+ if (tok != TOK_LOR) {
4984+ if (t)
4985+ vseti(VT_JMP, t);
4986+ else
4987+ vpushi(0);
4988+ break;
4989+ }
4990+ next();
4991+ expr_land();
4992+ }
49814993 }
49824994 }
49834995
tests/tcctest.c+39−0
@@ -1232,6 +1232,38 @@ void optimize_out(void) · 1231 unmodified lines
12321232 printf("ool6:%d\n", defined_function());
12331233 goto breakhere;
12341234 }
1235+
1236+ /* Test that constants in logical && are optimized: */
1237+ i = 0 && undefined_function();
1238+ i = defined_function() && 0 && undefined_function();
1239+ if (0 && undefined_function())
1240+ undefined_function();
1241+ if (defined_function() && 0)
1242+ undefined_function();
1243+ if (0 && 0)
1244+ undefined_function();
1245+ if (defined_function() && 0 && undefined_function())
1246+ undefined_function();
1247+ /* The same for || : */
1248+ i = 1 || undefined_function();
1249+ i = defined_function() || 1 || undefined_function();
1250+ if (1 || undefined_function())
1251+ ;
1252+ else
1253+ undefined_function();
1254+ if (defined_function() || 1)
1255+ ;
1256+ else
1257+ undefined_function();
1258+ if (1 || 1)
1259+ ;
1260+ else
1261+ undefined_function();
1262+ if (defined_function() || 1 || undefined_function())
1263+ ;
1264+ else
1265+ undefined_function();
1266+
12351267 if (1)
12361268 return;
12371269 printf ("oor:%d\n", undefined_function());
@@ -2544,6 +2576,13 @@ void sizeof_test(void) · 1306 unmodified lines
25442576 /* And as direct sizeof argument (as unary expression): */
25452577 printf("sizeof (struct {short i; short j;}){4,5} = %d\n",
25462578 sizeof (struct {short i; short j;}){4,5} );
2579+
2580+ /* sizeof(x && y) should be sizeof(int), even if constant
2581+ evaluating is possible. */
2582+ printf("sizeof(t && 0) = %d\n", sizeof(t && 0));
2583+ printf("sizeof(1 && 1) = %d\n", sizeof(1 && 1));
2584+ printf("sizeof(t || 1) = %d\n", sizeof(t || 1));
2585+ printf("sizeof(0 || 0) = %d\n", sizeof(0 || 0));
25472586 }
25482587
25492588 void typeof_test(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