History

opt: Start optimizing dead code a bit

If a condition is always zero/non-zero we can omit the then or else code. This is complicated a bit by having to deal with labels that might make such code reachable without us yet knowing during parsing.

Michael Matz committed 10 years ago

Commit 31c7ea01 parent b303a004 files · +182 −2Browse files

Showing the changes to tests (3 of 4 files). Show all

Unified · Split

3 files
  1. tests/tcctest.c +27 −0
  2. tests/tests2/87_dead_code.c +122 −0
  3. tests/tests2/87_dead_code.expect +18 −0
tests/tcctest.c+27−0
@@ -88,6 +88,7 @@ void struct_test(); · 87 unmodified lines
88void array_test();88void array_test();
89void expr_ptr_test();89void expr_ptr_test();
90void bool_test();90void bool_test();
91void optimize_out();
91void expr2_test();92void expr2_test();
92void constant_expr_test();93void constant_expr_test();
93void expr_cmp_test();94void expr_cmp_test();
@@ -695,6 +696,7 @@ int main(int argc, char **argv) · 601 unmodified lines
695 array_test();696 array_test();
696 expr_ptr_test();697 expr_ptr_test();
697 bool_test();698 bool_test();
699 optimize_out();
698 expr2_test();700 expr2_test();
699 constant_expr_test();701 constant_expr_test();
700 expr_cmp_test();702 expr_cmp_test();
@@ -1165,6 +1167,31 @@ void bool_test() · 464 unmodified lines
1165 printf ("bits = 0x%x\n", calc_vm_flags (0x1));1167 printf ("bits = 0x%x\n", calc_vm_flags (0x1));
1166}1168}
1167 1169
1170extern int undefined_function(void);
1171extern int defined_function(void);
1172
1173void optimize_out(void)
1174{
1175 int i = 0 ? undefined_function() : defined_function();
1176 printf ("oo:%d\n", i);
1177 int j = 1 ? defined_function() : undefined_function();
1178 printf ("oo:%d\n", j);
1179 if (0)
1180 printf("oo:%d\n", undefined_function());
1181 else
1182 printf("oo:%d\n", defined_function());
1183 if (1)
1184 printf("oo:%d\n", defined_function());
1185 else
1186 printf("oo:%d\n", undefined_function());
1187}
1188
1189int defined_function(void)
1190{
1191 static int i = 40;
1192 return i++;
1193}
1194
1168/* GCC accepts that */1195/* GCC accepts that */
1169static int tab_reinit[];1196static int tab_reinit[];
1170static int tab_reinit[10];1197static int tab_reinit[10];
tests/tests2/87_dead_code.c+122−0
@@ -0,0 +1,122 @@
1/* This checks various ways of dead code inside if statements
2 where there are non-obvious ways of how the code is actually
3 not dead due to reachable by labels. */
4extern int printf (const char *, ...);
5static void kb_wait_1(void)
6{
7 unsigned long timeout = 2;
8 do {
9 /* Here the else arm is a statement expression that's supposed
10 to be suppressed. The label inside the while would unsuppress
11 code generation again if not handled correctly. And that
12 would wreak havok to the cond-expression because there's no
13 jump-around emitted, the whole statement expression really
14 needs to not generate code (perhaps except useless forward jumps). */
15 (1 ?
16 printf("timeout=%ld\n", timeout) :
17 ({
18 int i = 1;
19 while (1)
20 while (i--)
21 some_label:
22 printf("error\n");
23 goto some_label;
24 })
25 );
26 timeout--;
27 } while (timeout);
28}
29int main (void)
30{
31 int i = 1;
32 kb_wait_1();
33
34 /* Simple test of dead code at first sight which isn't actually dead. */
35 if (0) {
36yeah:
37 printf ("yeah\n");
38 } else {
39 printf ("boo\n");
40 }
41 if (i--)
42 goto yeah;
43
44 /* Some more non-obvious uses where the problems are loops, so that even
45 the first loop statements aren't actually dead. */
46 i = 1;
47 if (0) {
48 while (i--) {
49 printf ("once\n");
50enterloop:
51 printf ("twice\n");
52 }
53 }
54 if (i >= 0)
55 goto enterloop;
56
57 /* The same with statement expressions. One might be tempted to
58 handle them specially by counting if inside statement exprs and
59 not unsuppressing code at loops at all then.
60 See kb_wait_1 for the other side of the medal where that wouldn't work. */
61 i = ({
62 int j = 1;
63 if (0) {
64 while (j--) {
65 printf ("SEonce\n");
66 enterexprloop:
67 printf ("SEtwice\n");
68 }
69 }
70 if (j >= 0)
71 goto enterexprloop;
72 j; });
73
74 /* The other two loop forms: */
75 i = 1;
76 if (0) {
77 for (i = 1; i--;) {
78 printf ("once2\n");
79enterloop2:
80 printf ("twice2\n");
81 }
82 }
83 if (i > 0)
84 goto enterloop2;
85
86 i = 1;
87 if (0) {
88 do {
89 printf ("once3\n");
90enterloop3:
91 printf ("twice3\n");
92 } while (i--);
93 }
94 if (i > 0)
95 goto enterloop3;
96
97 /* And check that case and default labels have the same effect
98 of disabling code suppression. */
99 i = 41;
100 switch (i) {
101 if (0) {
102 printf ("error\n");
103 case 42:
104 printf ("error2\n");
105 case 41:
106 printf ("caseok\n");
107 }
108 }
109
110 i = 41;
111 switch (i) {
112 if (0) {
113 printf ("error3\n");
114 default:
115 printf ("caseok2\n");
116 break;
117 case 42:
118 printf ("error4\n");
119 }
120 }
121 return 0;
122}
tests/tests2/87_dead_code.expect+18−0
@@ -0,0 +1,18 @@
1timeout=2
2timeout=1
3boo
4yeah
5twice
6once
7twice
8SEtwice
9SEonce
10SEtwice
11twice2
12once2
13twice2
14twice3
15once3
16twice3
17caseok
18caseok2

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