Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions include/blocks/declaration_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef DECLARATION_UTILS_H
#define DECLARATION_UTILS_H

#include "blocks/stmt.h"

namespace block {

bool is_splittable(decl_stmt::Ptr decl);
std::vector<decl_stmt::Ptr> find_declarations(stmt::Ptr scope);
void split_declarations(stmt::Ptr scope, std::vector<decl_stmt::Ptr> &declarations);

} // namespace block
#endif
10 changes: 10 additions & 0 deletions include/blocks/loop_normalizer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ifndef LOOP_NORMALIZER_H
#define LOOP_NORMALIZER_H

#include "blocks/stmt.h"

namespace block {
void normalize_loop_backedges(stmt::Ptr ast);
}

#endif
49 changes: 49 additions & 0 deletions samples/outputs.var_names/sample67
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
int generated_same_body (int arg0) {
int i_0 = 0;
int z_1 = 0;
if (i_0 < arg0) {
z_1 = z_1 + 1;
i_0 = i_0 + 1;
}
while (i_0 < arg0) {
z_1 = z_1 + 1;
i_0 = i_0 + 1;
}
return z_1;
}

int generated_different_prefix (int arg0) {
int i_0 = 0;
int a_1 = 0;
int b_2 = 0;
if (i_0 < arg0) {
b_2 = b_2 + 1;
i_0 = i_0 + 1;
}
while (i_0 < arg0) {
a_1 = a_1 + 1;
i_0 = i_0 + 1;
}
int var3 = a_1 + b_2;
return var3;
}

int generated_followed_by_loop (int arg0) {
int i_0 = 0;
int j_1 = 0;
int z_2 = 0;
if (i_0 < arg0) {
z_2 = z_2 + 1;
i_0 = i_0 + 1;
}
while (i_0 < arg0) {
z_2 = z_2 + 1;
i_0 = i_0 + 1;
}
while (j_1 < arg0) {
z_2 = z_2 + 1;
j_1 = j_1 + 1;
}
return z_2;
}

49 changes: 49 additions & 0 deletions samples/outputs/sample67
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
int generated_same_body (int arg0) {
int var0 = 0;
int var1 = 0;
if (var0 < arg0) {
var1 = var1 + 1;
var0 = var0 + 1;
}
while (var0 < arg0) {
var1 = var1 + 1;
var0 = var0 + 1;
}
return var1;
}

int generated_different_prefix (int arg0) {
int var0 = 0;
int var1 = 0;
int var2 = 0;
if (var0 < arg0) {
var2 = var2 + 1;
var0 = var0 + 1;
}
while (var0 < arg0) {
var1 = var1 + 1;
var0 = var0 + 1;
}
int var3 = var1 + var2;
return var3;
}

int generated_followed_by_loop (int arg0) {
int var0 = 0;
int var1 = 0;
int var2 = 0;
if (var0 < arg0) {
var2 = var2 + 1;
var0 = var0 + 1;
}
while (var0 < arg0) {
var2 = var2 + 1;
var0 = var0 + 1;
}
while (var1 < arg0) {
var2 = var2 + 1;
var1 = var1 + 1;
}
return var2;
}

66 changes: 66 additions & 0 deletions samples/sample67.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include "blocks/c_code_generator.h"
#include "builder/builder_context.h"
#include "builder/dyn_var.h"
#include <iostream>

using builder::dyn_var;

static dyn_var<int> same_body(dyn_var<int> n) {
dyn_var<int> i(0);
dyn_var<int> z(0);
if (i < n) {
z = z + 1;
i = i + 1;
}
while (i < n) {
z = z + 1;
i = i + 1;
}
return z;
}

static dyn_var<int> different_prefix(dyn_var<int> n) {
dyn_var<int> i(0);
dyn_var<int> a(0);
dyn_var<int> b(0);
if (i < n) {
b = b + 1;
i = i + 1;
}
while (i < n) {
a = a + 1;
i = i + 1;
}
return a + b;
}

static dyn_var<int> followed_by_loop(dyn_var<int> n) {
dyn_var<int> i(0);
dyn_var<int> j(0);
dyn_var<int> z(0);
if (i < n) {
z = z + 1;
i = i + 1;
}
while (i < n) {
z = z + 1;
i = i + 1;
}
while (j < n) {
z = z + 1;
j = j + 1;
}
return z;
}

int main() {
builder::builder_context context;
auto same_body_ast = context.extract_function_ast(same_body, "generated_same_body");
block::c_code_generator::generate_code(same_body_ast, std::cout, 0);

auto different_prefix_ast = context.extract_function_ast(different_prefix, "generated_different_prefix");
block::c_code_generator::generate_code(different_prefix_ast, std::cout, 0);

auto followed_by_loop_ast = context.extract_function_ast(followed_by_loop, "generated_followed_by_loop");
block::c_code_generator::generate_code(followed_by_loop_ast, std::cout, 0);
}
86 changes: 86 additions & 0 deletions src/blocks/declaration_utils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#include "blocks/declaration_utils.h"
#include "blocks/block_visitor.h"

namespace block {
namespace {

class declaration_finder : public block_visitor {
public:
using block_visitor::visit;
std::vector<decl_stmt::Ptr> declarations;

void visit(decl_stmt::Ptr declaration) override {
for (auto existing : declarations)
if (existing->decl_var == declaration->decl_var)
return;
declarations.push_back(declaration);
}
};

static bool contains_var(const std::vector<decl_stmt::Ptr> &declarations, var::Ptr var) {
for (auto declaration : declarations)
if (declaration->decl_var == var)
return true;
return false;
}

class declaration_splitter : public block_visitor {
std::vector<decl_stmt::Ptr> &declarations;

public:
using block_visitor::visit;
explicit declaration_splitter(std::vector<decl_stmt::Ptr> &declarations) : declarations(declarations) {}

void visit(stmt_block::Ptr block) override {
for (unsigned int i = 0; i < block->stmts.size();) {
if (!isa<decl_stmt>(block->stmts[i]) ||
!contains_var(declarations, to<decl_stmt>(block->stmts[i])->decl_var)) {
block->stmts[i]->accept(this);
i++;
continue;
}

auto declaration = to<decl_stmt>(block->stmts[i]);
if (!declaration->init_expr) {
block->stmts.erase(block->stmts.begin() + i);
continue;
}

auto lhs = std::make_shared<var_expr>();
lhs->static_offset = declaration->static_offset;
lhs->var1 = declaration->decl_var;
auto assignment = std::make_shared<assign_expr>();
assignment->static_offset = declaration->static_offset;
assignment->var1 = lhs;
assignment->expr1 = declaration->init_expr;
auto replacement = std::make_shared<expr_stmt>();
replacement->static_offset = declaration->static_offset;
replacement->metadata_map = declaration->metadata_map;
replacement->annotation = declaration->annotation;
replacement->expr1 = assignment;
block->stmts[i] = replacement;
i++;
}
}
};

} // namespace

bool is_splittable(decl_stmt::Ptr decl) {
type::Ptr type = decl->decl_var->var_type;
return !decl->is_typedef && !decl->is_extern && !decl->is_static && !type->is_const &&
!isa<reference_type>(type) && !isa<array_type>(type) && !isa<function_type>(type);
}

std::vector<decl_stmt::Ptr> find_declarations(stmt::Ptr scope) {
declaration_finder finder;
scope->accept(&finder);
return finder.declarations;
}

void split_declarations(stmt::Ptr scope, std::vector<decl_stmt::Ptr> &declarations) {
declaration_splitter splitter(declarations);
scope->accept(&splitter);
}

} // namespace block
73 changes: 3 additions & 70 deletions src/blocks/for_loop_finder.cpp
Original file line number Diff line number Diff line change
@@ -1,24 +1,8 @@
#include "blocks/for_loop_finder.h"
#include "blocks/declaration_utils.h"

namespace block {

class declaration_finder : public block_visitor {
public:
using block_visitor::visit;
std::vector<decl_stmt::Ptr> declarations;

void visit(decl_stmt::Ptr stmt) override {
declarations.push_back(stmt);
block_visitor::visit(stmt);
}
};

static bool is_splittable(decl_stmt::Ptr decl) {
type::Ptr type = decl->decl_var->var_type;
return !decl->is_typedef && !decl->is_extern && !decl->is_static && !type->is_const &&
!isa<reference_type>(type) && !isa<array_type>(type) && !isa<function_type>(type);
}

static bool contains_var(const std::vector<decl_stmt::Ptr> &decls, var::Ptr var) {
for (auto decl : decls)
if (decl->decl_var == var)
Expand All @@ -27,10 +11,7 @@ static bool contains_var(const std::vector<decl_stmt::Ptr> &decls, var::Ptr var)
}

static bool find_declarations_to_hoist(stmt::Ptr body, expr::Ptr update, std::vector<decl_stmt::Ptr> &result) {
declaration_finder declarations;
body->accept(&declarations);

for (auto decl : declarations.declarations) {
for (auto decl : find_declarations(body)) {
var_use_finder uses;
uses.to_find = decl->decl_var;
update->accept(&uses);
Expand All @@ -44,53 +25,6 @@ static bool find_declarations_to_hoist(stmt::Ptr body, expr::Ptr update, std::ve
return true;
}

class declaration_splitter : public block_visitor {
std::vector<decl_stmt::Ptr> &to_split;

bool should_split(decl_stmt::Ptr decl) {
return contains_var(to_split, decl->decl_var);
}

public:
using block_visitor::visit;

declaration_splitter(std::vector<decl_stmt::Ptr> &to_split) : to_split(to_split) {}

void visit(stmt_block::Ptr block) override {
for (unsigned int i = 0; i < block->stmts.size();) {
if (!isa<decl_stmt>(block->stmts[i]) || !should_split(to<decl_stmt>(block->stmts[i]))) {
block->stmts[i]->accept(this);
i++;
continue;
}

decl_stmt::Ptr decl = to<decl_stmt>(block->stmts[i]);
if (decl->init_expr == nullptr) {
block->stmts.erase(block->stmts.begin() + i);
continue;
}

auto lhs = std::make_shared<var_expr>();
lhs->static_offset = decl->static_offset;
lhs->var1 = decl->decl_var;

auto assign = std::make_shared<assign_expr>();
assign->static_offset = decl->static_offset;
assign->var1 = lhs;
assign->expr1 = decl->init_expr;

auto replacement = std::make_shared<expr_stmt>();
replacement->static_offset = decl->static_offset;
replacement->metadata_map = decl->metadata_map;
replacement->annotation = decl->annotation;
replacement->expr1 = assign;

block->stmts[i] = replacement;
i++;
}
}
};

static bool use_update(expr::Ptr candidate, expr::Ptr &update) {
if (update == nullptr) {
update = candidate;
Expand Down Expand Up @@ -303,8 +237,7 @@ void for_loop_finder::visit(stmt_block::Ptr a) {
for_loop->update = ce;
}

declaration_splitter splitter(declarations_to_hoist);
loop->body->accept(&splitter);
split_declarations(loop->body, declarations_to_hoist);

for_loop->body = loop->body;
new_stmts.push_back(for_loop);
Expand Down
6 changes: 6 additions & 0 deletions src/blocks/loop_finder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,12 @@ void loop_finder::visit_label(label_stmt::Ptr a, stmt_block::Ptr parent) {
}

if (last_stmt == nullptr) {
last_jump_finder global_jump_finder;
global_jump_finder.jump_label = a->label1;
ast->accept(&global_jump_finder);
if (global_jump_finder.has_jump_to)
return;

// 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
Expand Down
Loading
Loading