diff --git a/include/blocks/basic_blocks.h b/include/blocks/basic_blocks.h index 937ccd2..afe7055 100644 --- a/include/blocks/basic_blocks.h +++ b/include/blocks/basic_blocks.h @@ -4,6 +4,7 @@ #include #include #include +#include class basic_block { public: @@ -18,6 +19,7 @@ class basic_block { unsigned int ast_depth; unsigned int id; std::string name; + // static std::map> ast_to_basic_block_map; }; basic_block::cfg_block generate_basic_blocks(block::stmt_block::Ptr ast); diff --git a/include/blocks/loops.h b/include/blocks/loops.h index 1242e7c..f909d3c 100644 --- a/include/blocks/loops.h +++ b/include/blocks/loops.h @@ -40,6 +40,7 @@ class loop_info { std::shared_ptr allocate_loop(std::shared_ptr header); block::stmt_block::Ptr convert_to_ast(block::stmt_block::Ptr ast); std::map> postorder_loops_map; + std::map> preorder_loops_map; std::vector> loops; std::vector> top_level_loops; @@ -48,6 +49,7 @@ class loop_info { dominator_analysis dta; std::map> bb_loop_map; void postorder_dfs_helper(std::vector &postorder_loops_map, std::vector &visited_loops, int id); + void preorder_dfs_helper(std::vector &preorder_loops_map, std::vector &visited_loops, int id); // discover loops during traversal of the abstract syntax tree void analyze(); }; diff --git a/src/blocks/basic_blocks.cpp b/src/blocks/basic_blocks.cpp index 1261179..76656a3 100644 --- a/src/blocks/basic_blocks.cpp +++ b/src/blocks/basic_blocks.cpp @@ -13,6 +13,7 @@ basic_block::cfg_block generate_basic_blocks(block::stmt_block::Ptr ast) { for (auto st: ast->stmts) { auto bb = std::make_shared(std::to_string(basic_block_count)); bb->parent = st; + // bb->ast_to_basic_block_map[bb->parent] = bb; bb->ast_index = ast_index_counter++; bb->ast_depth = 0; work_list.push_back(bb); @@ -40,6 +41,7 @@ basic_block::cfg_block generate_basic_blocks(block::stmt_block::Ptr ast) { for (auto st: stmt_block_->stmts) { stmt_block_list.push_back(std::make_shared(std::to_string(basic_block_count++))); stmt_block_list.back()->parent = st; + // stmt_block_list.back()->ast_to_basic_block_map[bb->parent] = stmt_block_list.back(); stmt_block_list.back()->ast_index = ast_index_counter++; stmt_block_list.back()->ast_depth = bb->ast_depth + 1; } @@ -79,6 +81,8 @@ basic_block::cfg_block generate_basic_blocks(block::stmt_block::Ptr ast) { auto exit_bb = std::make_shared("exit" + std::to_string(basic_block_count)); // assign it a empty stmt_block as parent exit_bb->parent = std::make_shared(); + // add mapping in ast to bb map + // exit_bb->ast_to_basic_block_map[exit_bb->parent] = exit_bb; // set the ast depth of the basic block exit_bb->ast_depth = bb->ast_depth; // check if this is the last block, if yes the successor will be empty @@ -98,6 +102,8 @@ basic_block::cfg_block generate_basic_blocks(block::stmt_block::Ptr ast) { auto then_bb = std::make_shared(std::to_string(++basic_block_count)); // set the parent of this block as the then stmts then_bb->parent = if_stmt_->then_stmt; + // add mapping in ast to bb map + // then_bb->ast_to_basic_block_map[then_bb->parent] = then_bb; // set the ast depth of the basic block then_bb->ast_depth = bb->ast_depth; // set the successor of this block to be the exit block @@ -112,6 +118,8 @@ basic_block::cfg_block generate_basic_blocks(block::stmt_block::Ptr ast) { auto else_bb = std::make_shared(std::to_string(++basic_block_count)); // set the parent of this block as the else stmts else_bb->parent = if_stmt_->else_stmt; + // add mapping in ast to bb map + // else_bb->ast_to_basic_block_map[else_bb->parent] = else_bb; // set the ast depth of the basic block else_bb->ast_depth = bb->ast_depth; // set the successor of this block to be the exit block diff --git a/src/blocks/loops.cpp b/src/blocks/loops.cpp index 28cba63..833e219 100644 --- a/src/blocks/loops.cpp +++ b/src/blocks/loops.cpp @@ -1,5 +1,8 @@ #include "blocks/loops.h" #include +#include + +static std::vector>, stmt::Ptr>> worklist; std::shared_ptr loop_info::allocate_loop(std::shared_ptr header) { if (!header) @@ -20,6 +23,16 @@ void loop_info::postorder_dfs_helper(std::vector &postorder_loops_map, std: } } +void loop_info::preorder_dfs_helper(std::vector &preorder_loops_map, std::vector &visited_loops, int id) { + for (auto subloop: loops[id]->subloops) { + if (!visited_loops[subloop->loop_id]) { + visited_loops[subloop->loop_id] = true; + preorder_loops_map.push_back(subloop->loop_id); + preorder_dfs_helper(preorder_loops_map, visited_loops, subloop->loop_id); + } + } +} + void loop_info::analyze() { std::vector idom = dta.get_idom(); @@ -142,7 +155,7 @@ void loop_info::analyze() { loops[i]->loop_id = i; } - // build a loop tree + // build a postorder loop tree std::vector visited_loops(loops.size()); visited_loops.assign(visited_loops.size(), false); for (auto loop: top_level_loops) { @@ -153,14 +166,26 @@ void loop_info::analyze() { postorder_loop_tree.push_back(loop->loop_id); postorder_loops_map[loop->loop_id] = postorder_loop_tree; } + + // build a preorder loop tree + visited_loops.clear(); + visited_loops.assign(visited_loops.size(), false); + for (auto loop: top_level_loops) { + std::vector preorder_loop_tree; + visited_loops[loop->loop_id] = true; + + preorder_loop_tree.push_back(loop->loop_id); + preorder_dfs_helper(preorder_loop_tree, visited_loops, loop->loop_id); + preorder_loops_map[loop->loop_id] = preorder_loop_tree; + } } static stmt::Ptr get_loop_block(std::shared_ptr loop_header, block::stmt_block::Ptr ast) { block::stmt::Ptr current_ast = to(ast); std::vector current_block = to(current_ast)->stmts; - // unsigned int ast_index = loop_header->ast_index; std::deque worklist; std::map ast_parent_map; + std::cerr << loop_header->name << "\n"; for (auto stmt: current_block) { ast_parent_map[stmt] = current_ast; @@ -180,8 +205,9 @@ static stmt::Ptr get_loop_block(std::shared_ptr loop_header, block: } else if (isa(worklist_top)) { if_stmt::Ptr wl_if_stmt = to(worklist_top); - + std::cerr << "found if: "; if (to(wl_if_stmt->then_stmt)->stmts.size() != 0) { + std::cerr << "then\n"; stmt_block::Ptr wl_if_then_stmt = to(wl_if_stmt->then_stmt); for (auto stmt: wl_if_then_stmt->stmts) { ast_parent_map[stmt] = worklist_top; @@ -189,6 +215,7 @@ static stmt::Ptr get_loop_block(std::shared_ptr loop_header, block: worklist.insert(worklist.end(), wl_if_then_stmt->stmts.begin(), wl_if_then_stmt->stmts.end()); } if (to(wl_if_stmt->else_stmt)->stmts.size() != 0) { + std::cerr << "else\n"; stmt_block::Ptr wl_if_else_stmt = to(wl_if_stmt->else_stmt); for (auto stmt: wl_if_else_stmt->stmts) { ast_parent_map[stmt] = worklist_top; @@ -196,76 +223,151 @@ static stmt::Ptr get_loop_block(std::shared_ptr loop_header, block: worklist.insert(worklist.end(), wl_if_else_stmt->stmts.begin(), wl_if_else_stmt->stmts.end()); } } + else if (isa(worklist_top)) { + stmt_block::Ptr wl_while_body_block = to(to(worklist_top)->body); + for (auto stmt: wl_while_body_block->stmts) { + ast_parent_map[stmt] = worklist_top; + } + worklist.insert(worklist.end(), wl_while_body_block->stmts.begin(), wl_while_body_block->stmts.end()); + } else if (isa(worklist_top)) { + std::cerr << "found label\n"; + worklist_top->dump(std::cerr, 0); label_stmt::Ptr wl_label_stmt = to(worklist_top); if (worklist_top == loop_header->parent) return ast_parent_map[worklist_top]; } else if (isa(worklist_top)) { + std::cerr << "found goto\n"; goto_stmt::Ptr wl_goto_stmt = to(worklist_top); if (worklist_top == loop_header->parent) return ast_parent_map[worklist_top]; } } + std::cerr << "Returned nullptr !\n"; return nullptr; } +// remove continue if last basic block static void replace_loop_latches(std::shared_ptr loop, block::stmt_block::Ptr ast) { - for (auto latch : loop->loop_latch_blocks) { - stmt::Ptr loop_latch_ast = get_loop_block(latch, ast); + for (auto latch_iter = loop->loop_latch_blocks.begin(); latch_iter != loop->loop_latch_blocks.end(); latch_iter++) { + std::cerr << (*latch_iter)->ast_index << "\n"; + std::cerr << (*latch_iter)->parent.get() << "\n"; + stmt::Ptr loop_latch_ast = get_loop_block(*latch_iter, ast); + // loop_latch_ast->dump(std::cerr, 0); + if (isa(loop_latch_ast)) { - std::vector &temp_loop_ast = to(loop_latch_ast)->stmts; - std::replace(temp_loop_ast.begin(), temp_loop_ast.end(), temp_loop_ast[latch->ast_index], to(std::make_shared())); + std::cerr << "stmt parent\n"; + std::vector &temp_ast = to(loop_latch_ast)->stmts; + if (latch_iter == loop->loop_latch_blocks.end() - 1) + temp_ast.erase(temp_ast.begin() + (*latch_iter)->ast_index); + else + std::replace(temp_ast.begin(), temp_ast.end(), temp_ast[(*latch_iter)->ast_index + 1], to(std::make_shared())); } else if (isa(loop_latch_ast)) { stmt_block::Ptr if_then_block = to(to(loop_latch_ast)->then_stmt); stmt_block::Ptr if_else_block = to(to(loop_latch_ast)->else_stmt); - - if (if_then_block->stmts.size() && if_then_block->stmts[latch->ast_index] == latch->parent) { - std::replace(if_then_block->stmts.begin(), if_then_block->stmts.end(), if_then_block->stmts[latch->ast_index], to(std::make_shared())); + + std::cerr << "if parent: "; + std::cerr << if_then_block->stmts.size() << " " << if_else_block->stmts.size() << " " << (*latch_iter)->ast_index << " "; + if (if_then_block->stmts.size() && if_then_block->stmts[(*latch_iter)->ast_index] == (*latch_iter)->parent) { + std::cerr << "then\n"; + std::vector &temp_ast = if_then_block->stmts; + if (latch_iter == loop->loop_latch_blocks.end() - 1) + temp_ast.erase(temp_ast.begin() + (*latch_iter)->ast_index); + else + std::replace(temp_ast.begin(), temp_ast.end(), temp_ast[(*latch_iter)->ast_index], to(std::make_shared())); } - else if (if_else_block->stmts.size() && if_else_block->stmts[latch->ast_index] == latch->parent) { - std::replace(if_else_block->stmts.begin(), if_else_block->stmts.end(), if_else_block->stmts[latch->ast_index], to(std::make_shared())); + + if (if_else_block->stmts.size() && if_else_block->stmts[(*latch_iter)->ast_index] == (*latch_iter)->parent) { + std::cerr << "else\n"; + std::vector &temp_ast = if_else_block->stmts; + if (latch_iter == loop->loop_latch_blocks.end() - 1) + temp_ast.erase(temp_ast.begin() + (*latch_iter)->ast_index); + else + std::replace(temp_ast.begin(), temp_ast.end(), temp_ast[(*latch_iter)->ast_index], to(std::make_shared())); } } + + // loop_latch_ast->dump(std::cerr, 0); } } block::stmt_block::Ptr loop_info::convert_to_ast(block::stmt_block::Ptr ast) { + // std::cerr << "before ast\n"; + // ast->dump(std::cerr, 0); + // std::cerr << "before ast\n"; + + for (auto loop_map: preorder_loops_map) { + for (auto preorder: loop_map.second) { + replace_loop_latches(loops[preorder], ast); + } + } + + // std::cerr << "after ast\n"; + // ast->dump(std::cerr, 0); + // std::cerr << "after ast\n"; + for (auto loop_map: postorder_loops_map) { - // std::cerr << "== top level loop tree ==\n"; for (auto postorder: loop_map.second) { - // std::cerr << postorder <<"\n"; + std::cerr << "before ast\n"; + ast->dump(std::cerr, 0); + std::cerr << "before ast\n"; block::stmt::Ptr loop_header_ast = get_loop_block(loops[postorder]->header_block, ast); - + std::cerr << loops[postorder]->header_block->ast_index << "\n"; + loop_header_ast->dump(std::cerr, 0); while_stmt::Ptr while_block = std::make_shared(); - while_block->cond = std::make_shared(); - to(while_block->cond)->value = 1; while_block->body = std::make_shared(); + if (isa(loop_header_ast)) { + loop_header_ast = to(loop_header_ast)->body; + } + if (isa(loop_header_ast)) { unsigned int ast_index = loops[postorder]->header_block->ast_index; - if (to(loop_header_ast)->stmts[ast_index] == loops[postorder]->header_block->parent) { + // handle unconditional loops + if (to(loop_header_ast)->stmts[ast_index] == loops[postorder]->header_block->parent && !isa(to(loop_header_ast)->stmts[ast_index + 1])) { + for (auto bb: loops[postorder]->blocks) { + to(while_block->body)->stmts.push_back(bb->parent); + } + // pop loop backedge + to(while_block->body)->stmts.pop_back(); + + // set always true condition + while_block->cond = std::make_shared(); + to(while_block->cond)->value = 1; + + // unconditional loops can have only one backedge !? + assert(loops[postorder]->loop_latch_blocks.size() == 1); + for (unsigned int i = ast_index + 2; i < loops[postorder]->loop_latch_blocks[0]->ast_index; i++) { + std::cerr << i << "\n"; + worklist.push_back(std::make_tuple(i, std::ref(to(loop_header_ast)->stmts), nullptr)); + } + + worklist.push_back(std::make_tuple(ast_index, std::ref(to(loop_header_ast)->stmts), to(while_block))); + } + else if (to(loop_header_ast)->stmts[ast_index] == loops[postorder]->header_block->parent) { stmt_block::Ptr then_block = to(to(to(loop_header_ast)->stmts[ast_index + 1])->then_stmt); stmt_block::Ptr else_block = to(to(to(loop_header_ast)->stmts[ast_index + 1])->else_stmt); + std::cerr << "stmt block\n"; + + while_block->cond = to(to(loop_header_ast)->stmts[ast_index + 1])->cond; + if (then_block->stmts.size() == 0 && else_block->stmts.size() != 0) { + not_expr::Ptr new_cond = std::make_shared(); + new_cond->static_offset = while_block->cond->static_offset; + new_cond->expr1 = while_block->cond; + while_block->cond = new_cond; + } - // if (isa(then_block->stmts.back())) { - // then_block->stmts.pop_back(); - // then_block->stmts.push_back(std::make_shared()); - // } - replace_loop_latches(loops[postorder], ast); - - else_block->stmts.push_back(std::make_shared()); - to(while_block->body)->stmts.push_back(to(loop_header_ast)->stmts[ast_index + 1]); - // while_block->cond = to(to(loop_header_ast)->stmts[ast_index + 1])->cond; - // while_block->dump(std::cerr, 0); - // std::cerr << "found loop header in stmt block\n"; - + for (auto body_stmt: then_block->stmts) { + to(while_block->body)->stmts.push_back(body_stmt); + } + for (auto body_stmt: else_block->stmts) { + to(while_block->body)->stmts.push_back(body_stmt); + } // if block to be replaced with while block - std::vector &temp_ast = to(loop_header_ast)->stmts; - std::replace(temp_ast.begin(), temp_ast.end(), temp_ast[ast_index + 1], to(while_block)); - temp_ast.erase(temp_ast.begin() + ast_index); + worklist.push_back(std::make_tuple(ast_index, std::ref(to(loop_header_ast)->stmts), to(while_block))); } else { // std::cerr << "not found loop header in stmt block\n"; @@ -277,50 +379,97 @@ block::stmt_block::Ptr loop_info::convert_to_ast(block::stmt_block::Ptr ast) { stmt_block::Ptr if_else_block = to(to(loop_header_ast)->else_stmt); if (if_then_block->stmts.size() != 0) { - if (if_then_block->stmts[ast_index] == loops[postorder]->header_block->parent) { + std::cerr << "if then block\n"; + // handle unconditional loops + if (if_then_block->stmts[ast_index] == loops[postorder]->header_block->parent && !isa(if_then_block->stmts[ast_index + 1])) { + for (auto bb: loops[postorder]->blocks) { + to(while_block->body)->stmts.push_back(bb->parent); + } + // pop loop backedge + to(while_block->body)->stmts.pop_back(); + + // set always true condition + while_block->cond = std::make_shared(); + to(while_block->cond)->value = 1; + + // unconditional loops can have only one backedge !? + assert(loops[postorder]->loop_latch_blocks.size() == 1); + for (unsigned int i = ast_index + 2; i < loops[postorder]->loop_latch_blocks[0]->ast_index; i++) { + worklist.push_back(std::make_tuple(i, std::ref(to(loop_header_ast)->stmts), nullptr)); + } + + worklist.push_back(std::make_tuple(ast_index, std::ref(to(loop_header_ast)->stmts), to(while_block))); + } + else if (if_then_block->stmts[ast_index] == loops[postorder]->header_block->parent) { stmt_block::Ptr then_block = to(to(if_then_block->stmts[ast_index + 1])->then_stmt); stmt_block::Ptr else_block = to(to(if_then_block->stmts[ast_index + 1])->else_stmt); - replace_loop_latches(loops[postorder], ast); - - else_block->stmts.push_back(std::make_shared()); - to(while_block->body)->stmts.push_back(if_then_block->stmts[ast_index + 1]); - // while_block->cond = to(loop_header_ast)->cond; - - // while_block->dump(std::cerr, 0); - // std::cerr << "found loop header in if-then stmt\n"; - + while_block->cond = to(if_then_block->stmts[ast_index + 1])->cond; + if (then_block->stmts.size() == 0 && else_block->stmts.size() != 0) { + not_expr::Ptr new_cond = std::make_shared(); + new_cond->static_offset = while_block->cond->static_offset; + new_cond->expr1 = while_block->cond; + while_block->cond = new_cond; + } + + + for (auto body_stmt: then_block->stmts) { + to(while_block->body)->stmts.push_back(body_stmt); + } + for (auto body_stmt: else_block->stmts) { + to(while_block->body)->stmts.push_back(body_stmt); + } // if block to be replaced with while block - std::vector &temp_ast = if_then_block->stmts; - std::replace(temp_ast.begin(), temp_ast.end(), temp_ast[ast_index + 1], to(while_block)); - temp_ast.erase(temp_ast.begin() + ast_index); + worklist.push_back(std::make_tuple(ast_index, std::ref(if_then_block->stmts), to(while_block))); } else { - // loop_header_ast->dump(std::cerr, 0); // std::cerr << "not found loop header in if-then stmt\n"; } } else if (if_else_block->stmts.size() != 0) { - if (if_else_block->stmts[ast_index] == loops[postorder]->header_block->parent) { + std::cerr << "if else block\n"; + // handle unconditional loops + if (if_else_block->stmts[ast_index] == loops[postorder]->header_block->parent && !isa(if_else_block->stmts[ast_index + 1])) { + for (auto bb: loops[postorder]->blocks) { + to(while_block->body)->stmts.push_back(bb->parent); + } + // pop loop backedge + to(while_block->body)->stmts.pop_back(); + + // set always true condition + while_block->cond = std::make_shared(); + to(while_block->cond)->value = 1; + + // unconditional loops can have only one backedge !? + assert(loops[postorder]->loop_latch_blocks.size() == 1); + for (unsigned int i = ast_index + 2; i < loops[postorder]->loop_latch_blocks[0]->ast_index; i++) { + worklist.push_back(std::make_tuple(i, std::ref(to(loop_header_ast)->stmts), nullptr)); + } + + worklist.push_back(std::make_tuple(ast_index, std::ref(to(loop_header_ast)->stmts), to(while_block))); + } + else if (if_else_block->stmts[ast_index] == loops[postorder]->header_block->parent) { stmt_block::Ptr then_block = to(to(if_else_block->stmts[ast_index + 1])->then_stmt); stmt_block::Ptr else_block = to(to(if_else_block->stmts[ast_index + 1])->else_stmt); - replace_loop_latches(loops[postorder], ast); - - else_block->stmts.push_back(std::make_shared()); - to(while_block->body)->stmts.push_back(if_else_block->stmts[ast_index + 1]); - // while_block->cond = to(loop_header_ast)->cond; - - // while_block->dump(std::cerr, 0); - // std::cerr << "found loop header in if-else stmt\n"; - + while_block->cond = to(if_else_block->stmts[ast_index + 1])->cond; + if (then_block->stmts.size() == 0 && else_block->stmts.size() != 0) { + not_expr::Ptr new_cond = std::make_shared(); + new_cond->static_offset = while_block->cond->static_offset; + new_cond->expr1 = while_block->cond; + while_block->cond = new_cond; + } + + for (auto body_stmt: then_block->stmts) { + to(while_block->body)->stmts.push_back(body_stmt); + } + for (auto body_stmt: else_block->stmts) { + to(while_block->body)->stmts.push_back(body_stmt); + } // if block to be replaced with while block - std::vector &temp_ast = if_else_block->stmts; - std::replace(temp_ast.begin(), temp_ast.end(), temp_ast[ast_index + 1], to(while_block)); - temp_ast.erase(temp_ast.begin() + ast_index); + worklist.push_back(std::make_tuple(ast_index, std::ref(if_else_block->stmts), to(while_block))); } else { - // loop_header_ast->dump(std::cerr, 0); // std::cerr << "not found loop header in if-else stmt\n"; } } @@ -328,9 +477,30 @@ block::stmt_block::Ptr loop_info::convert_to_ast(block::stmt_block::Ptr ast) { else { // std::cerr << "loop header not found\n"; } - // insert into AST - std::replace - // set the ast to loop depth + 1 - // loops[loop_tree.first]->header_block->ast_index + + // process worklist + std::sort(worklist.begin(), worklist.end(), [](std::tuple>, stmt::Ptr> a, std::tuple>, stmt::Ptr> b) { + return std::get<0>(a) > std::get<0>(b); + }); + for (auto item : worklist) { + std::vector &temp_ast = std::get<1>(item); + if (std::get<2>(item)) { + std::replace(temp_ast.begin(), temp_ast.end(), temp_ast[std::get<0>(item) + 1], std::get<2>(item)); + temp_ast.erase(temp_ast.begin() + std::get<0>(item)); + } + } + + for (auto item : worklist) { + std::vector &temp_ast = std::get<1>(item); + if (!std::get<2>(item)) { + temp_ast.erase(temp_ast.begin() + std::get<0>(item)); + } + } + worklist.clear(); + + std::cerr << "after ast\n"; + ast->dump(std::cerr, 0); + std::cerr << "after ast\n"; } } diff --git a/src/builder/builder_context.cpp b/src/builder/builder_context.cpp index 269ccdf..4cb1907 100644 --- a/src/builder/builder_context.cpp +++ b/src/builder/builder_context.cpp @@ -393,12 +393,21 @@ block::stmt::Ptr builder_context::extract_ast_from_function_impl(void) { std::cerr << "\n"; std::cerr << "++++++ preorder loops tree ++++++ \n"; + for (auto loop_tree: LI.preorder_loops_map) { + std::cerr << "loop tree root: (loop header: " << LI.loops[loop_tree.first]->header_block->id << ")\n"; + std::cerr << "preorder: "; + for (auto node: loop_tree.second) std::cerr << node << " "; + std::cerr << "\n"; + } + + std::cerr << "++++++ postorder loops tree ++++++ \n"; for (auto loop_tree: LI.postorder_loops_map) { std::cerr << "loop tree root: (loop header: " << LI.loops[loop_tree.first]->header_block->id << ")\n"; std::cerr << "postorder: "; for (auto node: loop_tree.second) std::cerr << node << " "; std::cerr << "\n"; } + std::cerr << "++++++ loop info ++++++ \n"; std::cerr << "++++++ convert to ast ++++++ \n"; @@ -408,9 +417,9 @@ block::stmt::Ptr builder_context::extract_ast_from_function_impl(void) { if (feature_unstructured) return ast; - // block::loop_finder finder; - // finder.ast = ast; - // ast->accept(&finder); + block::loop_finder finder; + finder.ast = ast; + ast->accept(&finder); block::for_loop_finder for_finder; for_finder.ast = ast; @@ -505,7 +514,7 @@ block::stmt::Ptr builder_context::extract_ast_from_function_internal(std::vector ret_ast = ast; } catch (LoopBackException &e) { current_builder_context = nullptr; - + std::cerr << "goto in\n"; block::goto_stmt::Ptr goto_stmt = std::make_shared(); goto_stmt->static_offset.clear(); goto_stmt->temporary_label_number = e.static_offset; @@ -515,13 +524,23 @@ block::stmt::Ptr builder_context::extract_ast_from_function_internal(std::vector } catch (MemoizationException &e) { if (feature_unstructured) { // Instead of copying statements to the current block, we will just insert a goto + std::cerr << "goto memo\n"; block::goto_stmt::Ptr goto_stmt = std::make_shared(); goto_stmt->static_offset.clear(); goto_stmt->temporary_label_number = e.static_offset; add_stmt_to_current_block(goto_stmt, false); } else { + std::cerr << "goto memo\n"; for (unsigned int i = e.child_id; i < e.parent->stmts.size(); i++) { - add_stmt_to_current_block(e.parent->stmts[i], false); + if (isa(e.parent->stmts[i])) { + block::goto_stmt::Ptr goto_stmt = std::make_shared(); + goto_stmt->static_offset.clear(); + goto_stmt->temporary_label_number = to(e.parent->stmts[i])->temporary_label_number; + add_stmt_to_current_block(goto_stmt, false); + } + else { + add_stmt_to_current_block(e.parent->stmts[i], false); + } } } ret_ast = ast;