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
4909{4909{
4910 expr_or();4910 expr_or();
4911 if (tok == TOK_LAND) {4911 if (tok == TOK_LAND) {
4912 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {4912 int t = 0;
4913 CType ctb, cti;4913 for(;;) {
4914 ctb.t = VT_BOOL;4914 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4915 cti.t = VT_INT;4915 CType ctb;
4916 next();4916 ctb.t = VT_BOOL;
4917 gen_cast(&ctb);4917 gen_cast(&ctb);
4918 if (vtop->c.i) {4918 if (vtop->c.i) {
4919 vpop();4919 vpop();
4920 expr_land();4920 } else {
4921 gen_cast(&ctb);4921 int saved_nocode_wanted = nocode_wanted;
4922 } else {4922 nocode_wanted = 1;
4923 int saved_nocode_wanted = nocode_wanted;4923 while (tok == TOK_LAND) {
4924 nocode_wanted = 1;4924 next();
4925 expr_land();4925 expr_or();
4926 vpop();4926 vpop();
4927 nocode_wanted = saved_nocode_wanted;4927 }
4928 }4928 if (t)
4929 gen_cast(&cti);4929 gsym(t);
4930 } else {4930 nocode_wanted = saved_nocode_wanted;
4931 int t = 0;4931 gen_cast(&int_type);
4932 save_regs(1);4932 break;
4933 for(;;) {4933 }
4934 t = gvtst(1, t);4934 } else {
4935 if (tok != TOK_LAND) {4935 if (!t)
4936 vseti(VT_JMPI, t);4936 save_regs(1);
4937 break;4937 t = gvtst(1, t);
4938 }4938 }
4939 next();4939 if (tok != TOK_LAND) {
4940 expr_or();4940 if (t)
4941 }4941 vseti(VT_JMPI, t);
4942 }4942 else
4943 vpushi(1);
4944 break;
4945 }
4946 next();
4947 expr_or();
4948 }
4943 }4949 }
4944}4950}
4945 4951
@@ -4947,37 +4953,43 @@ static void expr_lor(void) · 1 unmodified line
4947{4953{
4948 expr_land();4954 expr_land();
4949 if (tok == TOK_LOR) {4955 if (tok == TOK_LOR) {
4950 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {4956 int t = 0;
4951 CType ctb, cti;4957 for(;;) {
4952 ctb.t = VT_BOOL;4958 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4953 cti.t = VT_INT;4959 CType ctb;
4954 next();4960 ctb.t = VT_BOOL;
4955 gen_cast(&ctb);4961 gen_cast(&ctb);
4956 if (vtop->c.i) {4962 if (!vtop->c.i) {
4957 int saved_nocode_wanted = nocode_wanted;4963 vpop();
4958 nocode_wanted = 1;4964 } else {
4959 expr_lor();4965 int saved_nocode_wanted = nocode_wanted;
4960 vpop();4966 nocode_wanted = 1;
4961 nocode_wanted = saved_nocode_wanted;4967 while (tok == TOK_LOR) {
4962 } else {4968 next();
4963 vpop();4969 expr_land();
4964 expr_lor();4970 vpop();
4965 gen_cast(&ctb);4971 }
4966 }4972 if (t)
4967 gen_cast(&cti);4973 gsym(t);
4968 } else {4974 nocode_wanted = saved_nocode_wanted;
4969 int t = 0;4975 gen_cast(&int_type);
4970 save_regs(1);4976 break;
4971 for(;;) {4977 }
4972 t = gvtst(0, t);4978 } else {
4973 if (tok != TOK_LOR) {4979 if (!t)
4974 vseti(VT_JMP, t);4980 save_regs(1);
4975 break;4981 t = gvtst(0, t);
4976 }4982 }
4977 next();4983 if (tok != TOK_LOR) {
4978 expr_land();4984 if (t)
4979 }4985 vseti(VT_JMP, t);
4980 }4986 else
4987 vpushi(0);
4988 break;
4989 }
4990 next();
4991 expr_land();
4992 }
4981 }4993 }
4982}4994}
4983 4995
tests/tcctest.c+39−0
@@ -1232,6 +1232,38 @@ void optimize_out(void) · 1231 unmodified lines
1232 printf("ool6:%d\n", defined_function());1232 printf("ool6:%d\n", defined_function());
1233 goto breakhere;1233 goto breakhere;
1234 }1234 }
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
1235 if (1)1267 if (1)
1236 return;1268 return;
1237 printf ("oor:%d\n", undefined_function());1269 printf ("oor:%d\n", undefined_function());
@@ -2544,6 +2576,13 @@ void sizeof_test(void) · 1306 unmodified lines
2544 /* And as direct sizeof argument (as unary expression): */2576 /* And as direct sizeof argument (as unary expression): */
2545 printf("sizeof (struct {short i; short j;}){4,5} = %d\n",2577 printf("sizeof (struct {short i; short j;}){4,5} = %d\n",
2546 sizeof (struct {short i; short j;}){4,5} );2578 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));
2547}2586}
2548 2587
2549void typeof_test(void)2588void 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