🎨 replace primitive size as constants

This commit is contained in:
ValKmjolnir 2024-11-16 01:08:05 +08:00
parent e1bdc57b74
commit bffec20b82
8 changed files with 88 additions and 29 deletions

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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";

View File

@ -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<sir*> 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<sir_call_func*>(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;
}
}

View File

@ -0,0 +1,42 @@
#pragma once
#include "sir/pass_manager.h"
#include <cstring>
#include <sstream>
#include <unordered_set>
#include <unordered_map>
namespace colgm {
class primitive_size_opt: public sir_pass {
private:
std::unordered_map<std::string, std::string> 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;
};
}

View File

@ -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;

View File

@ -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);