|
5 | 5 | #include "blocks/loop_finder.h" |
6 | 6 | #include "blocks/loop_roll.h" |
7 | 7 | #include "blocks/rce.h" |
| 8 | +#include "blocks/sub_expr_cleanup.h" |
8 | 9 | #include "blocks/var_namer.h" |
9 | 10 | #include "builder/builder.h" |
10 | 11 | #include "builder/dyn_var.h" |
@@ -97,18 +98,16 @@ void builder_context::remove_node_from_sequence(block::expr::Ptr e) { |
97 | 98 | } else { |
98 | 99 | // Could be committed already |
99 | 100 | // It is safe to update the parent block here, because the memoization doesn't care about indices |
100 | | - std::vector<block::stmt::Ptr> new_stmts; |
| 101 | + // But don't actually delete the statement, because there could be gotos that are jumping here |
| 102 | + // instead just mark it for deletion later |
101 | 103 | for (auto stmt : current_block_stmt->stmts) { |
102 | | - bool found = false; |
103 | 104 | if (block::isa<block::expr_stmt>(stmt)) { |
104 | 105 | auto expr_s = block::to<block::expr_stmt>(stmt); |
105 | | - if (expr_s->expr1 == e) |
106 | | - found = true; |
| 106 | + if (expr_s->expr1 == e) { |
| 107 | + expr_s->mark_for_deletion = true; |
| 108 | + } |
107 | 109 | } |
108 | | - if (!found) |
109 | | - new_stmts.push_back(stmt); |
110 | 110 | } |
111 | | - current_block_stmt->stmts = new_stmts; |
112 | 111 | } |
113 | 112 | } |
114 | 113 | void builder_context::add_node_to_sequence(block::expr::Ptr e) { |
@@ -284,6 +283,11 @@ block::stmt::Ptr builder_context::extract_ast_from_function_impl(void) { |
284 | 283 | inserter.offset_to_label = creator.offset_to_label; |
285 | 284 | ast->accept(&inserter); |
286 | 285 |
|
| 286 | + // At this point it is safe to remove statements that are |
| 287 | + // marked for deletion |
| 288 | + block::sub_expr_cleanup cleaner; |
| 289 | + ast->accept(&cleaner); |
| 290 | + |
287 | 291 | if (run_rce) { |
288 | 292 | block::eliminate_redundant_vars(ast); |
289 | 293 | } |
|
0 commit comments