|
1 | 1 | #include "builder/builder_context.h" |
2 | 2 | #include "blocks/for_loop_finder.h" |
3 | 3 | #include "blocks/if_switcher.h" |
| 4 | +#include "blocks/sub_expr_cleanup.h" |
4 | 5 | #include "blocks/label_inserter.h" |
5 | 6 | #include "blocks/loop_finder.h" |
6 | 7 | #include "blocks/loop_roll.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) { |
@@ -283,6 +282,11 @@ block::stmt::Ptr builder_context::extract_ast_from_function_impl(void) { |
283 | 282 | block::label_inserter inserter; |
284 | 283 | inserter.offset_to_label = creator.offset_to_label; |
285 | 284 | ast->accept(&inserter); |
| 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); |
286 | 290 |
|
287 | 291 | if (run_rce) { |
288 | 292 | block::eliminate_redundant_vars(ast); |
|
0 commit comments