diff --git a/include/blocks/block.h b/include/blocks/block.h index 0ee2241..6bcf46d 100644 --- a/include/blocks/block.h +++ b/include/blocks/block.h @@ -95,6 +95,9 @@ class block : public std::enable_shared_from_this { typename block_metadata::Ptr mdnode = metadata_map[mdname]; return mdnode->to()->val; } + bool getBoolMetadata(std::string mdname) { + return hasMetadata(mdname) && getMetadata(mdname); + } virtual void dump(std::ostream &, int); virtual void accept(block_visitor *visitor) { diff --git a/include/blocks/var_namer.h b/include/blocks/var_namer.h index 7a1eb68..b76d175 100644 --- a/include/blocks/var_namer.h +++ b/include/blocks/var_namer.h @@ -52,6 +52,12 @@ class var_hoister : public block_replacer { virtual void visit(decl_stmt::Ptr) override; }; +class var_reference_promoter : public block_replacer { +public: + using block_replacer::visit; + virtual void visit(var_expr::Ptr) override; +}; + } // namespace block #endif diff --git a/samples/outputs.var_names/sample54 b/samples/outputs.var_names/sample54 index bed524b..52f3f00 100644 --- a/samples/outputs.var_names/sample54 +++ b/samples/outputs.var_names/sample54 @@ -1,12 +1,18 @@ void bar (void) { - int z_1; + int z_3; + int* k_4; int y_0 = 0; + int m_1; + int n_2; if (y_0) { - z_1 = 1; + z_3 = 1; + k_4 = (&(m_1)); } else { - z_1 = 2; + z_3 = 2; + k_4 = (&(m_1)); } - int b_2; - int a_3 = z_1; + int b_5; + int a_6 = z_3; + z_3 = z_3 + k_4[0]; } diff --git a/samples/outputs/sample54 b/samples/outputs/sample54 index ad6453d..2e900f1 100644 --- a/samples/outputs/sample54 +++ b/samples/outputs/sample54 @@ -1,12 +1,18 @@ void bar (void) { - int var1; + int var3; + int* var4; int var0 = 0; + int var1; + int var2; if (var0) { - var1 = 1; + var3 = 1; + var4 = (&(var1)); } else { - var1 = 2; + var3 = 2; + var4 = (&(var1)); } - int var2; - int var3 = var1; + int var5; + int var6 = var3; + var3 = var3 + var4[0]; } diff --git a/samples/sample54.cpp b/samples/sample54.cpp index d8a5a94..f86909a 100644 --- a/samples/sample54.cpp +++ b/samples/sample54.cpp @@ -12,6 +12,7 @@ static void bar(void) { static_var x = 0; dyn_var y = 0; + dyn_var m, n; if (y) { x = 1; @@ -20,6 +21,7 @@ static void bar(void) { } // When z is declared, x is in different states dyn_var z = x; + dyn_var k = m; // Executions can now merge, but z is still in different states x = 0; @@ -30,6 +32,8 @@ static void bar(void) { // this statement now has issues because z has forked dyn_var a = z; + + z = z + k; } int main(int argc, char *argv[]) { diff --git a/src/blocks/loop_finder.cpp b/src/blocks/loop_finder.cpp index 7fc1a81..36ab18f 100644 --- a/src/blocks/loop_finder.cpp +++ b/src/blocks/loop_finder.cpp @@ -222,6 +222,21 @@ void loop_finder::visit_label(label_stmt::Ptr a, stmt_block::Ptr parent) { if (jump_finder.has_jump_to == true) last_stmt = stmt; } + + if (last_stmt == nullptr) { + // This label was created but has no jump. + // this currently happens when two statements have the same tag + // For now we will just delete this label + std::vector new_stmts; + for (auto stmt : parent->stmts) { + if (stmt == a) + continue; + new_stmts.push_back(stmt); + } + parent->stmts = new_stmts; + return; + } + std::vector::iterator stmt; for (stmt = parent->stmts.begin(); stmt != parent->stmts.end(); stmt++) { if (*stmt == a) diff --git a/src/blocks/var_namer.cpp b/src/blocks/var_namer.cpp index 9b35039..b30fc7b 100644 --- a/src/blocks/var_namer.cpp +++ b/src/blocks/var_namer.cpp @@ -63,6 +63,26 @@ void var_replacer::visit(var_expr::Ptr a) { void var_hoister::visit(decl_stmt::Ptr a) { std::string so = get_apt_tag(a->decl_var, escaping_tags); if (decls_to_hoist.find(so) != decls_to_hoist.end()) { + + // if the variable is of reference type, we need to convert it to a pointer + // type + + if (isa(a->decl_var->var_type)) { + auto ptr_type = std::make_shared(); + ptr_type->pointee_type = to(a->decl_var->var_type)->referenced_type; + a->decl_var->var_type = ptr_type; + assert(a->init_expr != nullptr && "Reference type declaration withtout a init expr"); + + a->decl_var->setMetadata("was_reference", true); + } + + if (a->decl_var->getBoolMetadata("was_reference")) { + auto addr_expr = std::make_shared(); + addr_expr->static_offset = a->init_expr->static_offset; + addr_expr->expr1 = a->init_expr; + a->init_expr = addr_expr; + } + // This decl needs to be flattened into an assignment // but if it doesn't have an init_expr, just make a simple var_expr expr_stmt::Ptr estmt = std::make_shared(); @@ -73,6 +93,8 @@ void var_hoister::visit(decl_stmt::Ptr a) { vexpr->static_offset = a->static_offset; vexpr->var1 = a->decl_var; + vexpr->setMetadata("is_reference_init", true); + if (a->init_expr == nullptr) { estmt->expr1 = vexpr; node = estmt; @@ -92,6 +114,24 @@ void var_hoister::visit(decl_stmt::Ptr a) { node = a; } +// This replacer replaces the uses of hoisted references +// to dereferences since they have been converted to pointers +void var_reference_promoter::visit(var_expr::Ptr a) { + node = a; + if (a->getBoolMetadata("is_reference_init") || !a->var1->getBoolMetadata("was_reference")) + return; + auto sq_bkt = std::make_shared(); + sq_bkt->static_offset = a->static_offset; + sq_bkt->var_expr = a; + auto index = std::make_shared(); + index->static_offset = a->static_offset; + index->value = 0; + index->is_64bit = false; + + sq_bkt->index = index; + node = sq_bkt; +} + void var_namer::name_vars(block::Ptr a) { var_namer namer; @@ -106,6 +146,9 @@ void var_namer::name_vars(block::Ptr a) { var_hoister hoister(namer.decls_to_hoist, namer.escaping_tags); a->accept(&hoister); + var_reference_promoter promoter; + a->accept(&promoter); + std::vector new_stmts; // Now insert all the hoisted decls at the top for (auto dt : namer.decl_tags_to_hoist) {