mirror of https://github.com/colgm/colgm.git
🎨 replace primitive size as constants
This commit is contained in:
parent
e1bdc57b74
commit
bffec20b82
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue