GCC Code Coverage Report


Directory: src/
File: script_transcompiler/optimization.cpp
Date: 2024-12-30 15:39:09
Exec Total Coverage
Lines: 152 165 92.1%
Functions: 12 12 100.0%
Branches: 151 238 63.4%

Line Branch Exec Source
1 #include "optimization.h"
2 #include "script.h"
3 #include <optional>
4
5 namespace
6 {
7
8 108 inline auto set_memory(intermediate::cmd cmd)
9 {
10
4/4
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 64 times.
108 return cmd == intermediate::cmd::text_memory ||
11 108 cmd == intermediate::cmd::load_memory;
12 }
13
14 4 void _remove_set_memory(data& data)
15 {
16 4 code temp;
17
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 temp.reserve(data.c.size());
18
19 4 std::optional<intermediate> prev;
20
21
2/2
✓ Branch 5 taken 108 times.
✓ Branch 6 taken 4 times.
112 for (const auto& line : data.c)
22 {
23
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if (line.command == intermediate::cmd::comment)
24 {
25 temp.push_back(line);
26 continue;
27 }
28
29
2/2
✓ Branch 1 taken 44 times.
✓ Branch 2 taken 64 times.
108 if (set_memory(line.command))
30 {
31
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 36 times.
44 if (prev.has_value())
32 {
33
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 const auto& prev_line = prev.value();
34
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
8 data.add_issue(issue::type::INFO, issue::phase::OPTIMIZAZION,
35 8 "Remove line.", prev_line.line,
36 8 prev_line.number);
37 }
38
39
1/2
✓ Branch 1 taken 44 times.
✗ Branch 2 not taken.
44 prev = line;
40 }
41 else
42 {
43
2/2
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 28 times.
64 if (prev.has_value())
44 {
45
2/4
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 36 times.
✗ Branch 5 not taken.
36 temp.push_back(prev.value());
46 36 prev = std::optional<intermediate>();
47 }
48
49
1/2
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
64 temp.push_back(line);
50 }
51 }
52
53
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if (prev.has_value())
54 temp.push_back(prev.value());
55
56
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 data.c = temp;
57 4 }
58
59 4 void _remove_redundant_process(data& data)
60 {
61 4 code temp;
62
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 temp.reserve(data.c.size());
63
64 4 std::optional<intermediate> prev;
65
66
2/2
✓ Branch 5 taken 100 times.
✓ Branch 6 taken 4 times.
104 for (const auto& line : data.c)
67 {
68
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
100 if (line.command == intermediate::cmd::comment)
69 {
70 temp.push_back(line);
71 continue;
72 }
73
74
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 76 times.
100 if (line.command == intermediate::cmd::process_memory)
75 {
76
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 16 times.
24 if (prev.has_value())
77 {
78
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 const auto& prev_line = prev.value();
79
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
8 data.add_issue(issue::type::INFO, issue::phase::OPTIMIZAZION,
80 8 "Remove line.", prev_line.line,
81 8 prev_line.number);
82 }
83
84
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 prev = line;
85 }
86 else
87 {
88
2/2
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 64 times.
76 if (prev.has_value())
89 {
90
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
12 temp.push_back(prev.value());
91 12 prev = std::optional<intermediate>();
92 }
93
94
1/2
✓ Branch 1 taken 76 times.
✗ Branch 2 not taken.
76 temp.push_back(line);
95 }
96 }
97
98
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 if (prev.has_value())
99
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 temp.push_back(prev.value());
100
101
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 data.c = temp;
102 4 }
103
104 88 inline auto block_start(intermediate::cmd cmd)
105 {
106
4/4
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 52 times.
88 return cmd == intermediate::cmd::load_memory ||
107 88 cmd == intermediate::cmd::text_memory;
108 }
109
110 36 void _remove_dangling_process(code& block, data& data)
111 {
112
113
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 32 times.
36 if (block.size() < 2)
114 4 return;
115
116
2/4
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 32 times.
✗ Branch 6 not taken.
32 const auto last_line = block.at(block.size() - 1);
117
118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 if (last_line.command == intermediate::cmd::process_memory)
119 {
120
121 data.add_issue(issue::type::INFO, issue::phase::OPTIMIZAZION,
122 "Remove 'process' without effect.", last_line.line,
123 last_line.number);
124
125 block.pop_back();
126 }
127 32 }
128
129 36 void _check_print_text(code& code_block)
130 {
131
1/2
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
36 auto copy = code_block;
132
133
2/2
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 24 times.
36 if (copy.size() != 2)
134 12 return;
135
136
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 const auto& first_line = copy.at(0);
137
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 const auto& second_line = copy.at(1);
138
139
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 20 times.
24 if (first_line.command != intermediate::cmd::text_memory)
140 4 return;
141
142
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 16 times.
20 if (second_line.command != intermediate::cmd::print_memory)
143 4 return;
144
145 16 code_block.clear();
146
2/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
16 code_block.push_back(intermediate{intermediate::cmd::print_text,
147
2/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
16 first_line.operand, first_line.line,
148 16 first_line.number, ""});
149
2/2
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 20 times.
36 }
150
151 36 void _check_save_text(code& code_block)
152 {
153
1/2
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
36 auto copy = code_block;
154
155
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 8 times.
36 if (copy.size() != 2)
156 28 return;
157
158
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 const auto& first_line = copy.at(0);
159
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 const auto& second_line = copy.at(1);
160
161
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (first_line.command != intermediate::cmd::text_memory)
162 4 return;
163
164
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (second_line.command != intermediate::cmd::save_memory)
165 return;
166
167 4 code_block.clear();
168
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 code_block.push_back(intermediate{intermediate::cmd::save_text,
169
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 first_line.operand, first_line.line,
170
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 first_line.number, second_line.operand});
171
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 32 times.
36 }
172
173 36 void _pre_process(code& block)
174 {
175
176
1/2
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
36 auto copy = block;
177
178
2/2
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 12 times.
36 if (copy.size() < 3)
179 24 return;
180
181
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
12 const auto first_line = copy.at(0);
182
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
12 const auto second_line = copy.at(1);
183
184
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 8 times.
12 if (first_line.command != intermediate::cmd::text_memory)
185 4 return;
186
187
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (second_line.command != intermediate::cmd::process_memory)
188 return;
189
190 // preprocess
191
192
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 script::engine engine(nullptr);
193
194
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 engine.run(script::command::TEXT, first_line.operand);
195
2/4
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
8 engine.run(script::command::PROCESS, "");
196
197
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 const auto res = engine.get_memory();
198
199 8 block.clear();
200
4/8
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 8 times.
✗ Branch 11 not taken.
16 block.push_back(intermediate{intermediate::cmd::text_memory, res,
201 8 first_line.line, first_line.number, ""});
202
203
2/2
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 8 times.
20 for (auto i = 2u; i < copy.size(); ++i)
204
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
12 block.push_back(copy.at(i));
205
6/6
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 4 times.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 4 times.
✓ Branch 9 taken 8 times.
✓ Branch 10 taken 28 times.
44 }
206
207 40 void _check_no_output(code& block, data& data)
208 {
209
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 36 times.
40 if (block.size() < 2)
210 4 return;
211
212 36 auto has_output = false;
213
214
2/2
✓ Branch 5 taken 84 times.
✓ Branch 6 taken 4 times.
88 for (const auto& line : block)
215 {
216
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 28 times.
84 if (line.command == intermediate::cmd::print_memory ||
217
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 52 times.
56 line.command == intermediate::cmd::save_memory)
218 32 return;
219 }
220
221
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (!has_output)
222 {
223
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 data.add_issue(issue::type::INFO, issue::phase::OPTIMIZAZION,
224 4 "Delete code block without effect.", block.at(0).line,
225 4 block.at(0).number);
226
227 4 block.clear();
228 }
229 }
230
231 } // namespace
232
233 // dead code removal; pre-processing
234 4 void optimizationA(data& data)
235 {
236 // dead code removal: setting memory
237
238 4 _remove_set_memory(data);
239 4 _remove_redundant_process(data);
240 4 }
241
242 4 void optimizationB(data& data)
243 {
244 4 std::vector<code> blocks;
245
246
2/2
✓ Branch 5 taken 92 times.
✓ Branch 6 taken 4 times.
96 for (const auto& line : data.c)
247 {
248
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 92 times.
92 if (line.command == intermediate::cmd::comment)
249 continue;
250
251
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 88 times.
92 if (line.command == intermediate::cmd::create_file)
252 {
253 4 code block;
254
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 block.push_back(line);
255
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 blocks.push_back(block);
256 4 continue;
257 4 }
258
259
2/2
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 52 times.
88 if (block_start(line.command))
260 {
261 36 code block;
262
1/2
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
36 blocks.push_back(block);
263 36 }
264
265
1/2
✓ Branch 3 taken 88 times.
✗ Branch 4 not taken.
88 blocks[blocks.size() - 1].push_back(line);
266 }
267
268 // optimize blocks
269
270
2/2
✓ Branch 5 taken 40 times.
✓ Branch 6 taken 4 times.
44 for (auto& block : blocks)
271 {
272
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 _check_no_output(block, data);
273
274
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 36 times.
40 if (block.empty())
275 4 continue;
276
277
1/2
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
36 _remove_dangling_process(block, data);
278
1/2
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
36 _pre_process(block);
279
1/2
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
36 _check_print_text(block);
280
1/2
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
36 _check_save_text(block);
281 }
282
283 // write blocks back
284
285 4 data.c.clear();
286
287
2/2
✓ Branch 5 taken 40 times.
✓ Branch 6 taken 4 times.
44 for (const auto& block : blocks)
288
2/2
✓ Branch 5 taken 56 times.
✓ Branch 6 taken 40 times.
96 for (const auto& line : block)
289
1/2
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
56 data.c.push_back(line);
290 4 }
291
292 4 void memory_init(data& data)
293 {
294
1/2
✓ Branch 5 taken 16 times.
✗ Branch 6 not taken.
16 for (auto& line : data.c)
295 {
296
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 12 times.
16 if (line.command == intermediate::cmd::text_memory)
297 {
298 4 line.command = intermediate::cmd::text_init_memory;
299 4 return;
300 }
301
302
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (line.command == intermediate::cmd::load_memory)
303 {
304 line.command = intermediate::cmd::load_init_memory;
305 return;
306 }
307 }
308 }
309