From bffec20b820e3c2b3ce6bc4cdefa34ae02f9f20f Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Sat, 16 Nov 2024 01:08:05 +0800 Subject: [PATCH] :art: replace primitive size as constants --- bootstrap/CMakeLists.txt | 1 + bootstrap/mir/add_default_func.cpp | 28 ------------------- bootstrap/mir/add_default_func.h | 1 - bootstrap/sir/pass_manager.cpp | 2 ++ bootstrap/sir/primitive_size_opt.cpp | 38 +++++++++++++++++++++++++ bootstrap/sir/primitive_size_opt.h | 42 ++++++++++++++++++++++++++++ bootstrap/sir/sir.h | 2 ++ src/ast/dumper.colgm | 3 ++ 8 files changed, 88 insertions(+), 29 deletions(-) create mode 100644 bootstrap/sir/primitive_size_opt.cpp create mode 100644 bootstrap/sir/primitive_size_opt.h diff --git a/bootstrap/CMakeLists.txt b/bootstrap/CMakeLists.txt index b85c17b..fd3e718 100644 --- a/bootstrap/CMakeLists.txt +++ b/bootstrap/CMakeLists.txt @@ -30,6 +30,7 @@ set(COLGM_SIR ${CMAKE_SOURCE_DIR}/sir/delete_useless_label.cpp ${CMAKE_SOURCE_DIR}/sir/detect_redef_extern.cpp ${CMAKE_SOURCE_DIR}/sir/pass_manager.cpp + ${CMAKE_SOURCE_DIR}/sir/primitive_size_opt.cpp ${CMAKE_SOURCE_DIR}/sir/remove_alloca.cpp ${CMAKE_SOURCE_DIR}/sir/sir.cpp) set(COLGM_MIR diff --git a/bootstrap/mir/add_default_func.cpp b/bootstrap/mir/add_default_func.cpp index dc2981e..91b369a 100644 --- a/bootstrap/mir/add_default_func.cpp +++ b/bootstrap/mir/add_default_func.cpp @@ -46,33 +46,6 @@ void add_default_func::add_main_impl() { ctx->impls.push_back(default_main); } -void add_default_func::add_primitive_size() { - struct prm_pair { const char* name; const char* size; }; - const prm_pair pairs[] = { - {"i64", "8"}, {"i32", "4"}, {"i16", "2"}, {"i8", "1"}, - {"u64", "8"}, {"u32", "4"}, {"u16", "2"}, {"u8", "1"}, - {"f32", "4"}, {"f64", "8"}, {"bool", "1"} - }; - for(auto i : pairs) { - const auto name = "@" + std::string(i.name) + ".__size__"; - if (used_funcs.count(name)) { - continue; - } - - auto size_impl = new mir_func; - size_impl->name = name; - size_impl->attributes = { "alwaysinline" }; - size_impl->return_type = type::u64_type(); - size_impl->block = new mir_block(span::null()); - auto return_stmt = new mir_return(span::null(), new mir_block(span::null())); - return_stmt->get_value()->add_content( - new mir_number(span::null(), i.size, type::u64_type()) - ); - size_impl->block->add_content(return_stmt); - ctx->impls.push_back(size_impl); - } -} - bool add_default_func::run(mir_context* c) { ctx = c; for(auto i : ctx->decls) { @@ -84,7 +57,6 @@ bool add_default_func::run(mir_context* c) { add_malloc_decl(); add_free_decl(); - add_primitive_size(); add_main_impl(); return true; diff --git a/bootstrap/mir/add_default_func.h b/bootstrap/mir/add_default_func.h index 04de006..e13c90a 100644 --- a/bootstrap/mir/add_default_func.h +++ b/bootstrap/mir/add_default_func.h @@ -17,7 +17,6 @@ private: void add_malloc_decl(); void add_free_decl(); void add_main_impl(); - void add_primitive_size(); public: ~add_default_func() override = default; diff --git a/bootstrap/sir/pass_manager.cpp b/bootstrap/sir/pass_manager.cpp index bdddb1f..7f5a241 100644 --- a/bootstrap/sir/pass_manager.cpp +++ b/bootstrap/sir/pass_manager.cpp @@ -2,6 +2,7 @@ #include "sir/delete_useless_label.h" #include "sir/remove_alloca.h" #include "sir/detect_redef_extern.h" +#include "sir/primitive_size_opt.h" #include "report.h" namespace colgm { @@ -16,6 +17,7 @@ void sir_pass_manager::execute(sir_context* sctx) { passes.push_back(new delete_useless_label); passes.push_back(new remove_alloca); passes.push_back(new detect_redef_extern); + passes.push_back(new primitive_size_opt); for(auto i : passes) { std::clog << "[" << green << "sir" << reset; std::clog << "] run " << i->name() << " pass...\n"; diff --git a/bootstrap/sir/primitive_size_opt.cpp b/bootstrap/sir/primitive_size_opt.cpp new file mode 100644 index 0000000..26ceae2 --- /dev/null +++ b/bootstrap/sir/primitive_size_opt.cpp @@ -0,0 +1,38 @@ +#include "sir/primitive_size_opt.h" + +namespace colgm { + +void primitive_size_opt::remove_primitive_size_method(sir_block* b) { + std::vector new_stmts = {}; + for(auto i : b->get_stmts()) { + if (i->get_ir_type() != sir_kind::sir_call_func) { + new_stmts.push_back(i); + continue; + } + auto p = static_cast(i); + if (primitive_methods.count(p->get_name())) { + auto constant = new sir_add( + value_t::literal(primitive_methods.at(p->get_name())), + value_t::literal("0"), + p->get_destination(), + true, + "i64" + ); + new_stmts.push_back(constant); + delete p; + ++replace_count; + } else { + new_stmts.push_back(i); + } + } + b->get_mut_stmts() = new_stmts; +} + +bool primitive_size_opt::run(sir_context* ctx) { + for(auto i : ctx->func_impls) { + remove_primitive_size_method(i->get_code_block()); + } + return true; +} + +} \ No newline at end of file diff --git a/bootstrap/sir/primitive_size_opt.h b/bootstrap/sir/primitive_size_opt.h new file mode 100644 index 0000000..cae215a --- /dev/null +++ b/bootstrap/sir/primitive_size_opt.h @@ -0,0 +1,42 @@ +#pragma once + +#include "sir/pass_manager.h" + +#include +#include +#include +#include + +namespace colgm { + +class primitive_size_opt: public sir_pass { +private: + std::unordered_map primitive_methods = { + {"i8.__size__", "1"}, {"i16.__size__", "2"}, + {"i32.__size__", "4"}, {"i64.__size__", "8"}, + {"u8.__size__", "1"}, {"u16.__size__", "2"}, + {"u32.__size__", "4"}, {"u64.__size__", "8"}, + {"f32.__size__", "4"}, {"f64.__size__", "8"}, + {"bool.__size__", "1"} + }; + u64 replace_count; + +private: + void remove_primitive_size_method(sir_block*); + +public: + primitive_size_opt(): sir_pass(), replace_count(0) {} + ~primitive_size_opt() override = default; + std::string name() override { + return "primitive size opt"; + } + std::string info() override { + return "replace " + + std::to_string(replace_count) + + " primitive size method call" + + (replace_count > 1 ? "s" : ""); + } + bool run(sir_context*) override; +}; + +} \ No newline at end of file diff --git a/bootstrap/sir/sir.h b/bootstrap/sir/sir.h index 5b906b7..1bdd4d5 100644 --- a/bootstrap/sir/sir.h +++ b/bootstrap/sir/sir.h @@ -279,6 +279,8 @@ public: sir(sir_kind::sir_call_func), name(n), return_type(rt), destination(dst) {} ~sir_call_func() override = default; + const auto& get_name() const { return name; } + const auto& get_destination() const { return destination; } void add_arg_type(const std::string& t) { args_type.push_back(t); } void add_arg(const value_t& a) { args.push_back(a); } void dump(std::ostream&) const override; diff --git a/src/ast/dumper.colgm b/src/ast/dumper.colgm index 701d9d4..0b2d009 100644 --- a/src/ast/dumper.colgm +++ b/src/ast/dumper.colgm @@ -627,6 +627,9 @@ impl ast_dumper { if (node->is_extern) { out.cyan().out("[extern]").reset(); } + if (node->is_public || node->is_extern) { + out.out(" "); + } out.green().out(node->name.c_str).reset(); out.out(" -> "); node->base.location->dump(out);