Skip to content

Commit

Permalink
Merge pull request #61 from AjayBrahmakshatriya/master
Browse files Browse the repository at this point in the history
Fixed var hoister to convert reference types to pointer types when hoisting
  • Loading branch information
AjayBrahmakshatriya authored Jan 1, 2024
2 parents 1a00369 + c1ed013 commit 6e7e4a1
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 10 deletions.
3 changes: 3 additions & 0 deletions include/blocks/block.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ class block : public std::enable_shared_from_this<block> {
typename block_metadata::Ptr mdnode = metadata_map[mdname];
return mdnode->to<T>()->val;
}
bool getBoolMetadata(std::string mdname) {
return hasMetadata<bool>(mdname) && getMetadata<bool>(mdname);
}

virtual void dump(std::ostream &, int);
virtual void accept(block_visitor *visitor) {
Expand Down
6 changes: 6 additions & 0 deletions include/blocks/var_namer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
16 changes: 11 additions & 5 deletions samples/outputs.var_names/sample54
Original file line number Diff line number Diff line change
@@ -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];
}

16 changes: 11 additions & 5 deletions samples/outputs/sample54
Original file line number Diff line number Diff line change
@@ -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];
}

4 changes: 4 additions & 0 deletions samples/sample54.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ static void bar(void) {
static_var<int> x = 0;

dyn_var<int> y = 0;
dyn_var<int> m, n;

if (y) {
x = 1;
Expand All @@ -20,6 +21,7 @@ static void bar(void) {
}
// When z is declared, x is in different states
dyn_var<int> z = x;
dyn_var<int &> k = m;

// Executions can now merge, but z is still in different states
x = 0;
Expand All @@ -30,6 +32,8 @@ static void bar(void) {

// this statement now has issues because z has forked
dyn_var<int> a = z;

z = z + k;
}

int main(int argc, char *argv[]) {
Expand Down
15 changes: 15 additions & 0 deletions src/blocks/loop_finder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<stmt::Ptr> new_stmts;
for (auto stmt : parent->stmts) {
if (stmt == a)
continue;
new_stmts.push_back(stmt);
}
parent->stmts = new_stmts;
return;
}

std::vector<stmt::Ptr>::iterator stmt;
for (stmt = parent->stmts.begin(); stmt != parent->stmts.end(); stmt++) {
if (*stmt == a)
Expand Down
43 changes: 43 additions & 0 deletions src/blocks/var_namer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<reference_type>(a->decl_var->var_type)) {
auto ptr_type = std::make_shared<pointer_type>();
ptr_type->pointee_type = to<reference_type>(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<bool>("was_reference", true);
}

if (a->decl_var->getBoolMetadata("was_reference")) {
auto addr_expr = std::make_shared<addr_of_expr>();
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<expr_stmt>();
Expand All @@ -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<bool>("is_reference_init", true);

if (a->init_expr == nullptr) {
estmt->expr1 = vexpr;
node = estmt;
Expand All @@ -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_expr>();
sq_bkt->static_offset = a->static_offset;
sq_bkt->var_expr = a;
auto index = std::make_shared<int_const>();
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;

Expand All @@ -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<stmt::Ptr> new_stmts;
// Now insert all the hoisted decls at the top
for (auto dt : namer.decl_tags_to_hoist) {
Expand Down

0 comments on commit 6e7e4a1

Please sign in to comment.