Skip to content

[feat] improve inst combine pass, optimize generated soufflé code #94

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Feb 11, 2025
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
22 changes: 9 additions & 13 deletions godel-script/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,8 @@ git reset HEAD~
Use command below:

```bash
mkdir build
cd build
cmake ..
make -j
mkdir build && cd build && cmake .. -DCMAKE_BUILD_TYPE=Release
make -j6
```

After building, you'll find `build/godel` in the `build` folder.
Expand All @@ -91,20 +89,18 @@ After building, you'll find `build/godel` in the `build` folder.

Use this command for help:

> ./build/godel -h
> godel -h

### Compile Target Soufflé
### Compile GödelScript to Target Soufflé

> ./build/godel -p {godel library directory} {input file} -s {soufflé output file} -Of
> godel -p {godel library directory} {input file} -s {soufflé output file} -O2

`-Of` is an optimization for join order, we suggest to switch it on.
We suggest to use `-O2` for stable optimizations.

### Directly Run Soufflé
### Directly Run GödelScript

> ./build/godel -p {godel library directory} {input file} -r -Of -f {database directory}
> godel -p {godel library directory} {input file} -r -O2 -f {database directory}

`-Of` is an optimization for join order, we suggest to switch it on.
We suggest to use `-O2` for stable optimizations.

`-r` means directly run soufflé.

`-v` could be used for getting verbose info.
6 changes: 3 additions & 3 deletions godel-script/godel-frontend/src/error/error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,13 +231,13 @@ void error::warn_ignored_DO_schema(const std::unordered_set<std::string>& vec) {
size_t ignored_count = 0;
for(const auto& i : vec) {
++ignored_count;
if (ignored_count > 4) {
if (ignored_count > 8) {
break;
}
std::clog << reset << " " << i << "\n";
}
if (vec.size() > 4) {
std::clog << reset << " ...(" << vec.size()-4 << ")\n";
if (vec.size() > 8) {
std::clog << reset << " ...(" << vec.size() - 8 << ")\n";
}
std::clog << std::endl;
}
Expand Down
135 changes: 122 additions & 13 deletions godel-script/godel-frontend/src/ir/inst_combine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ void inst_combine_pass::visit_store(lir::store* s) {
//
// (
// ssa_temp_0 = a,
// b = ssa_temp_1,
// ssa_temp_1 = b,
// call(ssa_temp_2, ssa_temp_0, ssa_temp_1)
// )
//
Expand Down Expand Up @@ -86,26 +86,67 @@ void inst_combine_pass::visit_compare(lir::compare* c) {
}
}

void inst_combine_pass::visit_call(lir::call* c) {
if (c->get_func_kind() != lir::call::kind::key_cmp) {
return;
}
if (c->get_function_name() != "key_eq") {
return;
}

const auto& left = c->get_arguments()[0];
const auto& right = c->get_arguments()[1];

// record this case:
//
// a.key_eq(b.getParent())
// -->
// (
// getParent(ssa_temp_0, b),
// a = ssa_temp_0
// )
//
// and optimize this case to:
//
// getParent(a, b)
//
if (left.kind==lir::inst_value_kind::variable &&
right.kind==lir::inst_value_kind::variable) {
variable_reference_graph[left.content].insert({right.content, c});
variable_reference_graph[right.content].insert({left.content, c});
}
}

bool inst_combine_pass::run() {
for(auto impl : ctx->rule_impls) {
scan(impl);
inst_elimination_worker().copy(impl);
for (auto impl : ctx->rule_impls) {
run_on_single_impl(impl);
}
for(auto impl : ctx->database_get_table) {
scan(impl);
inst_elimination_worker().copy(impl);
for (auto impl : ctx->database_get_table) {
run_on_single_impl(impl);
}
for(auto impl : ctx->schema_get_field) {
scan(impl);
inst_elimination_worker().copy(impl);
for (auto impl : ctx->schema_get_field) {
run_on_single_impl(impl);
}
for(auto impl : ctx->schema_data_constraint_impls) {
scan(impl);
inst_elimination_worker().copy(impl);
for (auto impl : ctx->schema_data_constraint_impls) {
run_on_single_impl(impl);
}
return true;
}

void inst_combine_pass::run_on_single_impl(souffle_rule_impl* b) {
auto worker = inst_elimination_worker();
size_t pass_run_count = 0;
const size_t max_pass_run_count = 16;
scan(b);
worker.copy(b);
++ pass_run_count;
while (worker.get_eliminated_count() && pass_run_count < max_pass_run_count) {
scan(b);
worker.copy(b);
++ pass_run_count;
}
}

void inst_combine_pass::scan(souffle_rule_impl* b) {
variable_reference_graph.clear();
b->get_block()->accept(this);
Expand Down Expand Up @@ -265,6 +306,7 @@ void inst_elimination_worker::visit_block(lir::block* node) {
for(auto i : node->get_content()) {
// skip eliminated instruction
if (i->get_flag_eliminated()) {
++ eliminated_count;
continue;
}

Expand Down Expand Up @@ -338,6 +380,8 @@ void inst_elimination_worker::visit_aggregator(lir::aggregator* node) {
}

void inst_elimination_worker::copy(souffle_rule_impl* impl) {
eliminated_count = 0;
blk.clear();
auto impl_blk = new lir::block(impl->get_block()->get_location());

blk.push_back(impl_blk);
Expand All @@ -354,4 +398,69 @@ void inst_elimination_worker::copy(souffle_rule_impl* impl) {
delete impl_blk;
}

void replace_find_call::visit_block(lir::block* node) {
bool has_find_call = false;
for (auto i : node->get_content()) {
if (i->get_kind() != lir::inst_kind::inst_call) {
continue;
}
auto call = reinterpret_cast<lir::call*>(i);
if (call->get_func_kind() == lir::call::kind::find &&
call->get_function_name() == "find") {
has_find_call = true;
break;
}
}

if (has_find_call) {
std::vector<lir::inst*> new_content;
for (auto i : node->get_content()) {
if (i->get_kind() != lir::inst_kind::inst_call) {
new_content.push_back(i);
continue;
}

auto call = reinterpret_cast<lir::call*>(i);
if (call->get_func_kind() != lir::call::kind::find ||
call->get_function_name() != "find") {
new_content.push_back(i);
continue;
}

auto dst = call->get_return();
auto arg0 = call->get_arguments()[0];
auto arg1 = call->get_arguments()[1];
auto new_block = new lir::block(call->get_location());
new_block->set_use_comma();
new_content.push_back(new_block);

new_block->add_new_content(new lir::store(arg0, dst, call->get_location()));
new_block->add_new_content(new lir::store(arg1, arg0, call->get_location()));

delete i;
}
node->get_mutable_content().swap(new_content);
} else {
for (auto i : node->get_content()) {
i->accept(this);
}
}
}

bool replace_find_call::run() {
for (auto impl : ctx->rule_impls) {
impl->get_block()->accept(this);
}
for (auto impl : ctx->database_get_table) {
impl->get_block()->accept(this);
}
for (auto impl : ctx->schema_get_field) {
impl->get_block()->accept(this);
}
for (auto impl : ctx->schema_data_constraint_impls) {
impl->get_block()->accept(this);
}
return true;
}

}
18 changes: 18 additions & 0 deletions godel-script/godel-frontend/src/ir/inst_combine.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ class inst_combine_pass: public pass {
private:
void visit_store(lir::store*) override;
void visit_compare(lir::compare*) override;
void visit_call(lir::call*) override;

private:
void scan(souffle_rule_impl*);
void run_on_single_impl(souffle_rule_impl*);

public:
inst_combine_pass(ir_context& c): pass(pass_kind::ps_inst_combine, c) {}
Expand Down Expand Up @@ -65,6 +67,7 @@ class combine_worker: public lir::inst_visitor {
class inst_elimination_worker: public lir::inst_visitor {
private:
std::vector<lir::block*> blk;
size_t eliminated_count = 0;

private:
void visit_boolean(lir::boolean* node) override {
Expand Down Expand Up @@ -111,6 +114,21 @@ class inst_elimination_worker: public lir::inst_visitor {

public:
void copy(souffle_rule_impl*);
auto get_eliminated_count() const {
return eliminated_count;
}
};

class replace_find_call: public pass {
private:
void visit_block(lir::block*) override;

public:
replace_find_call(ir_context& c): pass(pass_kind::ps_replace_find_call, c) {}
const char* get_name() const override {
return "[Transform] Replace Find Call";
}
bool run() override;
};

}
5 changes: 5 additions & 0 deletions godel-script/godel-frontend/src/ir/ir_gen.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,14 @@ class ir_gen: public ast_visitor {
std::vector<lir::call*>&,
bool);
bool visit_for_stmt(for_stmt*) override;
// adjust order of generated IR, to change the join order, make it running faster
// for statement often uses a large set, so this optimization is useful in most cases
void optimized_for_stmt_gen(for_stmt*);
void unoptimized_for_stmt_gen(for_stmt*);
bool visit_let_stmt(let_stmt*) override;
// adjust order of generated IR, to change the join order, make it running faster
// let statement often uses single value or a small set
// so this optimization is not very useful, or even harmful
void optimized_let_stmt_gen(let_stmt*);
void unoptimized_let_stmt_gen(let_stmt*);

Expand Down
1 change: 1 addition & 0 deletions godel-script/godel-frontend/src/ir/pass.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ enum class pass_kind {
ps_remove_unused,
ps_remove_unused_type,
ps_inst_combine,
ps_replace_find_call,
ps_flatten_nested_block,
ps_aggregator_inline_remark,
ps_ungrounded_check,
Expand Down
1 change: 1 addition & 0 deletions godel-script/godel-frontend/src/ir/pass_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ void pass_manager::run(ir_context& ctx, const cli::configure& conf) {
ordered_pass_list.push_back(new unused_type_alias_remove_pass(ctx));
}
if (!conf.count(cli::option::cli_disable_inst_combine)) {
ordered_pass_list.push_back(new replace_find_call(ctx));
ordered_pass_list.push_back(new inst_combine_pass(ctx));
}
ordered_pass_list.push_back(new flatten_nested_block(ctx));
Expand Down
Loading