diff --git a/include/lightir/BasicBlock.hpp b/include/lightir/BasicBlock.hpp index f749309f449321e00fe65a0afe996730fac7118d..a29a4a64612c4e2e7004ef7f5d3c54c92caf700a 100755 --- a/include/lightir/BasicBlock.hpp +++ b/include/lightir/BasicBlock.hpp @@ -81,11 +81,14 @@ class BasicBlock : public Value { // 用于 lldb 调试生成 summary std::string safe_print() const; + private: - explicit BasicBlock(Module *m, const std::string &name, Function *parent); + explicit BasicBlock(const Module *m, const std::string &name, Function *parent); std::list pre_bbs_; std::list succ_bbs_; std::list instr_list_; Function *parent_; }; + +extern Names GLOBAL_BASICBLOCK_NAMES_; \ No newline at end of file diff --git a/include/lightir/Function.hpp b/include/lightir/Function.hpp index f6e54308db3dee8d7befd08d6224ff7c838b6caf..0771c2f70a2b45b96182c1a438b759b047a3e0d0 100755 --- a/include/lightir/Function.hpp +++ b/include/lightir/Function.hpp @@ -7,6 +7,8 @@ #include #include +#include "Names.hpp" + class Module; class Argument; class Type; @@ -49,6 +51,11 @@ class Function : public Value { // 用于 lldb 调试生成 summary std::string safe_print() const; + + // 用于给 basicblock 分配名称 + Names names4blocks_; + Names names4insts_; + private: std::list basic_blocks_; std::list arguments_; diff --git a/include/lightir/IRBuilder.hpp b/include/lightir/IRBuilder.hpp index 9e4acac950c1d3e08827d73e8c0a838a149a6d99..a2d702a19c5fb58da10cf0251012ab3340ec0bde 100755 --- a/include/lightir/IRBuilder.hpp +++ b/include/lightir/IRBuilder.hpp @@ -105,9 +105,9 @@ class IRBuilder { return LoadInst::create_load(ptr, this->BB_); } - AllocaInst *create_alloca(Type *ty) const + AllocaInst *create_alloca(Type *ty, const std::string& name = "") const { - return AllocaInst::create_alloca(ty, this->BB_->get_entry_block_of_same_function()); + return AllocaInst::create_alloca(ty, this->BB_->get_entry_block_of_same_function(), name); } ZextInst *create_zext(Value *val, Type *ty) const diff --git a/include/lightir/Instruction.hpp b/include/lightir/Instruction.hpp index 694acc33d4fc27f08c5d1c6e0810d93dd14af4e3..3c027a52b0158ce66cec1816c66ed1330ce1cad7 100755 --- a/include/lightir/Instruction.hpp +++ b/include/lightir/Instruction.hpp @@ -1,5 +1,6 @@ #pragma once +#include "Names.hpp" #include "Type.hpp" #include "User.hpp" @@ -52,7 +53,7 @@ class Instruction : public User { }; /* @parent: if parent!=nullptr, auto insert to bb * @ty: result type */ - Instruction(Type *ty, OpID id, BasicBlock *parent = nullptr); + Instruction(Type *ty, OpID id, const std::string& name, BasicBlock *parent = nullptr); ~Instruction() override; Instruction(const Instruction& other) = delete; @@ -121,13 +122,13 @@ class Instruction : public User { class IBinaryInst : public Instruction { private: - IBinaryInst(OpID id, Value *v1, Value *v2, BasicBlock *bb); + IBinaryInst(OpID id, Value *v1, Value *v2, BasicBlock *bb, const std::string& name); public: - static IBinaryInst *create_add(Value *v1, Value *v2, BasicBlock *bb); - static IBinaryInst *create_sub(Value *v1, Value *v2, BasicBlock *bb); - static IBinaryInst *create_mul(Value *v1, Value *v2, BasicBlock *bb); - static IBinaryInst *create_sdiv(Value *v1, Value *v2, BasicBlock *bb); + static IBinaryInst *create_add(Value *v1, Value *v2, BasicBlock *bb, const std::string& name = ""); + static IBinaryInst *create_sub(Value *v1, Value *v2, BasicBlock *bb, const std::string& name = ""); + static IBinaryInst *create_mul(Value *v1, Value *v2, BasicBlock *bb, const std::string& name = ""); + static IBinaryInst *create_sdiv(Value *v1, Value *v2, BasicBlock *bb, const std::string& name = ""); std::string print() override; }; @@ -135,13 +136,13 @@ class IBinaryInst : public Instruction { class FBinaryInst : public Instruction { private: - FBinaryInst(OpID id, Value *v1, Value *v2, BasicBlock *bb); + FBinaryInst(OpID id, Value *v1, Value *v2, BasicBlock *bb, const std::string& name); public: - static FBinaryInst *create_fadd(Value *v1, Value *v2, BasicBlock *bb); - static FBinaryInst *create_fsub(Value *v1, Value *v2, BasicBlock *bb); - static FBinaryInst *create_fmul(Value *v1, Value *v2, BasicBlock *bb); - static FBinaryInst *create_fdiv(Value *v1, Value *v2, BasicBlock *bb); + static FBinaryInst *create_fadd(Value *v1, Value *v2, BasicBlock *bb, const std::string& name = ""); + static FBinaryInst *create_fsub(Value *v1, Value *v2, BasicBlock *bb, const std::string& name = ""); + static FBinaryInst *create_fmul(Value *v1, Value *v2, BasicBlock *bb, const std::string& name = ""); + static FBinaryInst *create_fdiv(Value *v1, Value *v2, BasicBlock *bb, const std::string& name = ""); std::string print() override; }; @@ -149,16 +150,16 @@ class FBinaryInst : public Instruction { class ICmpInst : public Instruction { private: - ICmpInst(OpID id, Value *lhs, Value *rhs, BasicBlock *bb); + ICmpInst(OpID id, Value *lhs, Value *rhs, BasicBlock *bb, const std::string& name); public: - static ICmpInst *create_ge(Value *v1, Value *v2, BasicBlock *bb); - static ICmpInst *create_gt(Value *v1, Value *v2, BasicBlock *bb); - static ICmpInst *create_le(Value *v1, Value *v2, BasicBlock *bb); - static ICmpInst *create_lt(Value *v1, Value *v2, BasicBlock *bb); - static ICmpInst *create_eq(Value *v1, Value *v2, BasicBlock *bb); - static ICmpInst *create_ne(Value *v1, Value *v2, BasicBlock *bb); + static ICmpInst *create_ge(Value *v1, Value *v2, BasicBlock *bb, const std::string& name = ""); + static ICmpInst *create_gt(Value *v1, Value *v2, BasicBlock *bb, const std::string& name = ""); + static ICmpInst *create_le(Value *v1, Value *v2, BasicBlock *bb, const std::string& name = ""); + static ICmpInst *create_lt(Value *v1, Value *v2, BasicBlock *bb, const std::string& name = ""); + static ICmpInst *create_eq(Value *v1, Value *v2, BasicBlock *bb, const std::string& name = ""); + static ICmpInst *create_ne(Value *v1, Value *v2, BasicBlock *bb, const std::string& name = ""); std::string print() override; }; @@ -166,15 +167,15 @@ class ICmpInst : public Instruction { class FCmpInst : public Instruction { private: - FCmpInst(OpID id, Value *lhs, Value *rhs, BasicBlock *bb); + FCmpInst(OpID id, Value *lhs, Value *rhs, BasicBlock *bb, const std::string& name); public: - static FCmpInst *create_fge(Value *v1, Value *v2, BasicBlock *bb); - static FCmpInst *create_fgt(Value *v1, Value *v2, BasicBlock *bb); - static FCmpInst *create_fle(Value *v1, Value *v2, BasicBlock *bb); - static FCmpInst *create_flt(Value *v1, Value *v2, BasicBlock *bb); - static FCmpInst *create_feq(Value *v1, Value *v2, BasicBlock *bb); - static FCmpInst *create_fne(Value *v1, Value *v2, BasicBlock *bb); + static FCmpInst *create_fge(Value *v1, Value *v2, BasicBlock *bb, const std::string& name = ""); + static FCmpInst *create_fgt(Value *v1, Value *v2, BasicBlock *bb, const std::string& name = ""); + static FCmpInst *create_fle(Value *v1, Value *v2, BasicBlock *bb, const std::string& name = ""); + static FCmpInst *create_flt(Value *v1, Value *v2, BasicBlock *bb, const std::string& name = ""); + static FCmpInst *create_feq(Value *v1, Value *v2, BasicBlock *bb, const std::string& name = ""); + static FCmpInst *create_fne(Value *v1, Value *v2, BasicBlock *bb, const std::string& name = ""); std::string print() override; }; @@ -182,11 +183,11 @@ class FCmpInst : public Instruction { class CallInst : public Instruction { protected: - CallInst(Function *func, const std::vector& args, BasicBlock *bb); + CallInst(Function *func, const std::vector& args, BasicBlock *bb, const std::string& name); public: static CallInst *create_call(Function *func, const std::vector& args, - BasicBlock *bb); + BasicBlock *bb, const std::string& name = ""); FunctionType *get_function_type() const; std::string print() override; @@ -232,12 +233,12 @@ class ReturnInst : public Instruction { class GetElementPtrInst : public Instruction { private: - GetElementPtrInst(Value *ptr, const std::vector& idxs, BasicBlock *bb); + GetElementPtrInst(Value *ptr, const std::vector& idxs, BasicBlock *bb, const std::string& name); public: - static Type *get_element_type(const Value *ptr, const std::vector& idxs); + static Type *get_element_type(const Value *ptr, const std::vector& idxs, const std::string& name = ""); static GetElementPtrInst *create_gep(Value *ptr, const std::vector& idxs, - BasicBlock *bb); + BasicBlock *bb, const std::string& name = ""); Type *get_element_type() const; std::string print() override; @@ -258,10 +259,10 @@ class StoreInst : public Instruction { class LoadInst : public Instruction { - LoadInst(Value *ptr, BasicBlock *bb); + LoadInst(Value *ptr, BasicBlock *bb, const std::string& name); public: - static LoadInst *create_load(Value *ptr, BasicBlock *bb); + static LoadInst *create_load(Value *ptr, BasicBlock *bb, const std::string& name = ""); Value *get_lval() const { return this->get_operand(0); } Type *get_load_type() const { return get_type(); } @@ -271,11 +272,11 @@ class LoadInst : public Instruction { class AllocaInst : public Instruction { - AllocaInst(Type *ty, BasicBlock *bb); + AllocaInst(Type *ty, BasicBlock *bb, const std::string& name); public: // 新特性:指令表分为 {alloca, phi | other inst} 两段,创建和向基本块插入 alloca 和 phi,都只会插在第一段,它们在常规指令前面 - static AllocaInst *create_alloca(Type *ty, BasicBlock *bb); + static AllocaInst *create_alloca(Type *ty, BasicBlock *bb, const std::string& name = ""); Type *get_alloca_type() const { return get_type()->get_pointer_element_type(); @@ -287,11 +288,11 @@ class AllocaInst : public Instruction { class ZextInst : public Instruction { private: - ZextInst(Value *val, Type *ty, BasicBlock *bb); + ZextInst(Value *val, Type *ty, BasicBlock *bb, const std::string& name); public: - static ZextInst *create_zext(Value *val, Type *ty, BasicBlock *bb); - static ZextInst *create_zext_to_i32(Value *val, BasicBlock *bb); + static ZextInst *create_zext(Value *val, Type *ty, BasicBlock *bb, const std::string& name = ""); + static ZextInst *create_zext_to_i32(Value *val, BasicBlock *bb, const std::string& name = ""); Type *get_dest_type() const { return get_type(); } @@ -301,11 +302,11 @@ class ZextInst : public Instruction { class FpToSiInst : public Instruction { private: - FpToSiInst(Value *val, Type *ty, BasicBlock *bb); + FpToSiInst(Value *val, Type *ty, BasicBlock *bb, const std::string& name); public: - static FpToSiInst *create_fptosi(Value *val, Type *ty, BasicBlock *bb); - static FpToSiInst *create_fptosi_to_i32(Value *val, BasicBlock *bb); + static FpToSiInst *create_fptosi(Value *val, Type *ty, BasicBlock *bb, const std::string& name = ""); + static FpToSiInst *create_fptosi_to_i32(Value *val, BasicBlock *bb, const std::string& name = ""); Type *get_dest_type() const { return get_type(); } @@ -315,10 +316,10 @@ class FpToSiInst : public Instruction { class SiToFpInst : public Instruction { private: - SiToFpInst(Value *val, Type *ty, BasicBlock *bb); + SiToFpInst(Value *val, Type *ty, BasicBlock *bb, const std::string& name); public: - static SiToFpInst *create_sitofp(Value *val, BasicBlock *bb); + static SiToFpInst *create_sitofp(Value *val, BasicBlock *bb, const std::string& name = ""); Type *get_dest_type() const { return get_type(); } @@ -329,13 +330,13 @@ class PhiInst : public Instruction { private: PhiInst(Type *ty, const std::vector& vals, - const std::vector& val_bbs, BasicBlock *bb); + const std::vector& val_bbs, BasicBlock *bb, const std::string& name); public: // 新特性:指令表分为 {alloca, phi | other inst} 两段,创建和向基本块插入 alloca 和 phi,都只会插在第一段,它们在常规指令前面 static PhiInst *create_phi(Type *ty, BasicBlock *bb, const std::vector& vals = {}, - const std::vector& val_bbs = {}); + const std::vector& val_bbs = {}, const std::string& name = ""); void add_phi_pair_operand(Value *val, Value *pre_bb) { this->add_operand(val); @@ -354,3 +355,5 @@ class PhiInst : public Instruction { std::string print() override; }; + +extern Names GLOBAL_INSTRUCTION_NAMES_; \ No newline at end of file diff --git a/include/lightir/Names.hpp b/include/lightir/Names.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f5bda39776493f5eb23e40f0076d91df436a74aa --- /dev/null +++ b/include/lightir/Names.hpp @@ -0,0 +1,27 @@ +#ifndef NAMES_HPP +#define NAMES_HPP +#include +#include + +class Names +{ +public: + explicit Names(bool use_underline, std::string prefix, std::string append) + : use_underline_(use_underline), default_prefix_used_count_(0), default_prefix_(std::move(prefix)), + appended_prefix_(std::move(append)) + { + } + + // 获得一个 Names 内唯一的名称,会保持唯一的同时尽可能的与 names 类似 + std::string get_name(std::string name); + // 获得一个 Names 内唯一的名称 + std::string get_name(); + +private: + bool use_underline_; + int default_prefix_used_count_; + std::string default_prefix_; + std::string appended_prefix_; + std::unordered_map allocated_; +}; +#endif // !NAMES_HPP diff --git a/src/cminusfc/cminusf_builder.cpp b/src/cminusfc/cminusf_builder.cpp index 7dbf43db47dc05545ca4f25dafde91f3ea7d81e5..d157eb8e51e861ec9728d00f0ba8f12caef0e959 100755 --- a/src/cminusfc/cminusf_builder.cpp +++ b/src/cminusfc/cminusf_builder.cpp @@ -91,7 +91,7 @@ Value* CminusfBuilder::visit(ASTVarDeclaration &node) { auto nowBB = builder->get_insert_block(); auto entryBB = context.func->get_entry_block(); builder->set_insert_point(entryBB); - auto *var = builder->create_alloca(var_type); + auto *var = builder->create_alloca(var_type, node.id); builder->set_insert_point(nowBB); scope.push(node.id, var); } else { @@ -99,7 +99,7 @@ Value* CminusfBuilder::visit(ASTVarDeclaration &node) { auto entryBB = context.func->get_entry_block(); builder->set_insert_point(entryBB); auto *array_type = ArrayType::get(var_type, node.num->i_val); - auto *var = builder->create_alloca(array_type); + auto *var = builder->create_alloca(array_type, node.id); builder->set_insert_point(nowBB); scope.push(node.id, var); } @@ -149,18 +149,18 @@ Value* CminusfBuilder::visit(ASTFunDeclaration &node) { if (node.params[i]->isarray) { Value *array_alloc; if (node.params[i]->type == TYPE_INT) { - array_alloc = builder->create_alloca(INT32PTR_T); + array_alloc = builder->create_alloca(INT32PTR_T, node.params[i]->id); } else { - array_alloc = builder->create_alloca(FLOATPTR_T); + array_alloc = builder->create_alloca(FLOATPTR_T, node.params[i]->id); } builder->create_store(args[i], array_alloc); scope.push(node.params[i]->id, array_alloc); } else { Value *alloc; if (node.params[i]->type == TYPE_INT) { - alloc = builder->create_alloca(INT32_T); + alloc = builder->create_alloca(INT32_T, node.params[i]->id); } else { - alloc = builder->create_alloca(FLOAT_T); + alloc = builder->create_alloca(FLOAT_T, node.params[i]->id); } builder->create_store(args[i], alloc); scope.push(node.params[i]->id, alloc); diff --git a/src/lightir/BasicBlock.cpp b/src/lightir/BasicBlock.cpp index 3ba36f3494189f9fc4281066e24c2540f3d63e4e..fc0e12963d1574f86aa4736fbd8027329dc63d18 100755 --- a/src/lightir/BasicBlock.cpp +++ b/src/lightir/BasicBlock.cpp @@ -7,9 +7,13 @@ #include -BasicBlock::BasicBlock(Module *m, const std::string &name = "", - Function *parent = nullptr) - : Value(m->get_label_type(), name), parent_(parent) { +#include "Names.hpp" + +BasicBlock::BasicBlock(const Module* m, const std::string& name = "", + Function* parent = nullptr) + : Value(m->get_label_type(), +parent == nullptr ? GLOBAL_BASICBLOCK_NAMES_.get_name(name) : parent->names4blocks_.get_name(name)) +, parent_(parent) { assert(parent && "currently parent should not be nullptr"); parent_->add_basic_block(this); } @@ -105,12 +109,9 @@ std::string BasicBlock::print() { std::string BasicBlock::safe_print() const { - Function* parent = parent_; - auto parentName = ((parent != nullptr) ? parent->get_name() : "f"); auto name = get_name(); if (name.empty()) name = "b" + ptr_to_str(this); - if (parentName.empty()) parentName = "f" + ptr_to_str(parent); - return parentName + ":" + name + " " + std::to_string(instr_list_.size()) + "inst pre " + std::to_string(pre_bbs_.size()) + "b suc " + std::to_string(succ_bbs_.size()) + "b"; + return name + " " + std::to_string(instr_list_.size()) + "inst pre " + std::to_string(pre_bbs_.size()) + "b suc " + std::to_string(succ_bbs_.size()) + "b"; } BasicBlock::~BasicBlock() @@ -123,3 +124,5 @@ BasicBlock* BasicBlock::get_entry_block_of_same_function() const assert(parent_ != nullptr && "bb have no parent function"); return parent_->get_entry_block(); } + +Names GLOBAL_BASICBLOCK_NAMES_{false, "label", ""}; \ No newline at end of file diff --git a/src/lightir/CMakeLists.txt b/src/lightir/CMakeLists.txt index 0442996c1c9eb6f8fbdee4204f00d356ff4ff486..10033ec45396103fa202bf7d87cd121970247706 100755 --- a/src/lightir/CMakeLists.txt +++ b/src/lightir/CMakeLists.txt @@ -10,7 +10,7 @@ add_library( Instruction.cpp Module.cpp IRprinter.cpp -) + Names.cpp) target_link_libraries( IR_lib diff --git a/src/lightir/Function.cpp b/src/lightir/Function.cpp index 813dd83f6ad5093746a9aad9037f6b4be3554369..051e717848ec384d374d725928ec8078e019ccb3 100755 --- a/src/lightir/Function.cpp +++ b/src/lightir/Function.cpp @@ -6,8 +6,17 @@ #include #include +namespace +{ + std::string chopName(std::string name) + { + if (name.size() > 4) return { name.begin(), name.begin() + 4 }; + return name; + } +} + Function::Function(FunctionType* ty, const std::string& name, Module* parent) - : Value(ty, name), parent_(parent), seq_cnt_(0) { + : Value(ty, name), names4blocks_(false, "label", chopName(name)), names4insts_(true, "op", ""), parent_(parent), seq_cnt_(0) { // num_args_ = ty->getNumParams(); parent->add_function(this); // build args diff --git a/src/lightir/Instruction.cpp b/src/lightir/Instruction.cpp index 9b06b4ca3c3b9412273a61ef74253e9d3b7e7568..f812740d56da39a9bd911663ff12a669ceae0038 100755 --- a/src/lightir/Instruction.cpp +++ b/src/lightir/Instruction.cpp @@ -10,10 +10,14 @@ #include #include -Instruction::Instruction(Type *ty, OpID id, BasicBlock *parent) +Instruction::Instruction(Type *ty, OpID id, const std::string& name, BasicBlock *parent) : User(ty, ""), op_id_(id), parent_(parent) { + assert(ty != nullptr && "Instruction have null type"); + assert(((!ty->is_void_type()) || name.empty()) && "Void Type Instruction should not have name"); if (parent) - parent->add_instruction(this); + parent->add_instruction(this); + if (!ty->is_void_type() && parent && parent->get_parent()) + set_name(parent_->get_parent()->names4insts_.get_name(name)); } Instruction::~Instruction() = default; @@ -25,50 +29,50 @@ std::string Instruction::get_instr_op_name() const { return print_instr_op_name(op_id_); } -IBinaryInst::IBinaryInst(OpID id, Value *v1, Value *v2, BasicBlock *bb) - : Instruction(bb->get_module()->get_int32_type(), id, bb) { +IBinaryInst::IBinaryInst(OpID id, Value *v1, Value *v2, BasicBlock *bb, const std::string& name) + : Instruction(bb->get_module()->get_int32_type(), id, name, bb) { assert(v1->get_type()->is_int32_type() && v2->get_type()->is_int32_type() && "IBinaryInst operands are not both i32"); add_operand(v1); add_operand(v2); } -IBinaryInst *IBinaryInst::create_add(Value *v1, Value *v2, BasicBlock *bb) { - return new IBinaryInst(add, v1, v2, bb); +IBinaryInst *IBinaryInst::create_add(Value *v1, Value *v2, BasicBlock *bb, const std::string& name) { + return new IBinaryInst(add, v1, v2, bb, name); } -IBinaryInst *IBinaryInst::create_sub(Value *v1, Value *v2, BasicBlock *bb) { - return new IBinaryInst(sub, v1, v2, bb); +IBinaryInst *IBinaryInst::create_sub(Value *v1, Value *v2, BasicBlock *bb, const std::string& name) { + return new IBinaryInst(sub, v1, v2, bb, name); } -IBinaryInst *IBinaryInst::create_mul(Value *v1, Value *v2, BasicBlock *bb) { - return new IBinaryInst(mul, v1, v2, bb); +IBinaryInst *IBinaryInst::create_mul(Value *v1, Value *v2, BasicBlock *bb, const std::string& name) { + return new IBinaryInst(mul, v1, v2, bb, name); } -IBinaryInst *IBinaryInst::create_sdiv(Value *v1, Value *v2, BasicBlock *bb) { - return new IBinaryInst(sdiv, v1, v2, bb); +IBinaryInst *IBinaryInst::create_sdiv(Value *v1, Value *v2, BasicBlock *bb, const std::string& name) { + return new IBinaryInst(sdiv, v1, v2, bb, name); } -FBinaryInst::FBinaryInst(OpID id, Value *v1, Value *v2, BasicBlock *bb) - : Instruction(bb->get_module()->get_float_type(), id, bb) { +FBinaryInst::FBinaryInst(OpID id, Value *v1, Value *v2, BasicBlock *bb, const std::string& name) + : Instruction(bb->get_module()->get_float_type(), id, name, bb) { assert(v1->get_type()->is_float_type() && v2->get_type()->is_float_type() && "FBinaryInst operands are not both float"); add_operand(v1); add_operand(v2); } -FBinaryInst *FBinaryInst::create_fadd(Value *v1, Value *v2, BasicBlock *bb) { - return new FBinaryInst(fadd, v1, v2, bb); +FBinaryInst *FBinaryInst::create_fadd(Value *v1, Value *v2, BasicBlock *bb, const std::string& name) { + return new FBinaryInst(fadd, v1, v2, bb, name); } -FBinaryInst *FBinaryInst::create_fsub(Value *v1, Value *v2, BasicBlock *bb) { - return new FBinaryInst(fsub, v1, v2, bb); +FBinaryInst *FBinaryInst::create_fsub(Value *v1, Value *v2, BasicBlock *bb, const std::string& name) { + return new FBinaryInst(fsub, v1, v2, bb,name); } -FBinaryInst *FBinaryInst::create_fmul(Value *v1, Value *v2, BasicBlock *bb) { - return new FBinaryInst(fmul, v1, v2, bb); +FBinaryInst *FBinaryInst::create_fmul(Value *v1, Value *v2, BasicBlock *bb, const std::string& name) { + return new FBinaryInst(fmul, v1, v2, bb,name); } -FBinaryInst *FBinaryInst::create_fdiv(Value *v1, Value *v2, BasicBlock *bb) { - return new FBinaryInst(fdiv, v1, v2, bb); +FBinaryInst *FBinaryInst::create_fdiv(Value *v1, Value *v2, BasicBlock *bb, const std::string& name) { + return new FBinaryInst(fdiv, v1, v2, bb,name); } -ICmpInst::ICmpInst(OpID id, Value *lhs, Value *rhs, BasicBlock *bb) - : Instruction(bb->get_module()->get_int1_type(), id, bb) { +ICmpInst::ICmpInst(OpID id, Value *lhs, Value *rhs, BasicBlock *bb, const std::string& name) + : Instruction(bb->get_module()->get_int1_type(), id,name, bb) { assert(lhs->get_type()->is_int32_type() && rhs->get_type()->is_int32_type() && "CmpInst operands are not both i32"); @@ -76,27 +80,27 @@ ICmpInst::ICmpInst(OpID id, Value *lhs, Value *rhs, BasicBlock *bb) add_operand(rhs); } -ICmpInst *ICmpInst::create_ge(Value *v1, Value *v2, BasicBlock *bb) { - return new ICmpInst(ge, v1, v2, bb); +ICmpInst *ICmpInst::create_ge(Value *v1, Value *v2, BasicBlock *bb, const std::string& name) { + return new ICmpInst(ge, v1, v2, bb, name); } -ICmpInst *ICmpInst::create_gt(Value *v1, Value *v2, BasicBlock *bb) { - return new ICmpInst(gt, v1, v2, bb); +ICmpInst *ICmpInst::create_gt(Value *v1, Value *v2, BasicBlock *bb, const std::string& name) { + return new ICmpInst(gt, v1, v2, bb, name); } -ICmpInst *ICmpInst::create_le(Value *v1, Value *v2, BasicBlock *bb) { - return new ICmpInst(le, v1, v2, bb); +ICmpInst *ICmpInst::create_le(Value *v1, Value *v2, BasicBlock *bb, const std::string& name) { + return new ICmpInst(le, v1, v2, bb, name); } -ICmpInst *ICmpInst::create_lt(Value *v1, Value *v2, BasicBlock *bb) { - return new ICmpInst(lt, v1, v2, bb); +ICmpInst *ICmpInst::create_lt(Value *v1, Value *v2, BasicBlock *bb, const std::string& name) { + return new ICmpInst(lt, v1, v2, bb, name); } -ICmpInst *ICmpInst::create_eq(Value *v1, Value *v2, BasicBlock *bb) { - return new ICmpInst(eq, v1, v2, bb); +ICmpInst *ICmpInst::create_eq(Value *v1, Value *v2, BasicBlock *bb, const std::string& name) { + return new ICmpInst(eq, v1, v2, bb, name); } -ICmpInst *ICmpInst::create_ne(Value *v1, Value *v2, BasicBlock *bb) { - return new ICmpInst(ne, v1, v2, bb); +ICmpInst *ICmpInst::create_ne(Value *v1, Value *v2, BasicBlock *bb, const std::string& name) { + return new ICmpInst(ne, v1, v2, bb, name); } -FCmpInst::FCmpInst(OpID id, Value *lhs, Value *rhs, BasicBlock *bb) - : Instruction(bb->get_module()->get_int1_type(), id, bb) { +FCmpInst::FCmpInst(OpID id, Value *lhs, Value *rhs, BasicBlock *bb, const std::string& name) + : Instruction(bb->get_module()->get_int1_type(), id, name, bb) { assert(lhs->get_type()->is_float_type() && rhs->get_type()->is_float_type() && "FCmpInst operands are not both float"); @@ -104,27 +108,27 @@ FCmpInst::FCmpInst(OpID id, Value *lhs, Value *rhs, BasicBlock *bb) add_operand(rhs); } -FCmpInst *FCmpInst::create_fge(Value *v1, Value *v2, BasicBlock *bb) { - return new FCmpInst(fge, v1, v2, bb); +FCmpInst *FCmpInst::create_fge(Value *v1, Value *v2, BasicBlock *bb, const std::string& name) { + return new FCmpInst(fge, v1, v2, bb, name); } -FCmpInst *FCmpInst::create_fgt(Value *v1, Value *v2, BasicBlock *bb) { - return new FCmpInst(fgt, v1, v2, bb); +FCmpInst *FCmpInst::create_fgt(Value *v1, Value *v2, BasicBlock *bb, const std::string& name) { + return new FCmpInst(fgt, v1, v2, bb, name); } -FCmpInst *FCmpInst::create_fle(Value *v1, Value *v2, BasicBlock *bb) { - return new FCmpInst(fle, v1, v2, bb); +FCmpInst *FCmpInst::create_fle(Value *v1, Value *v2, BasicBlock *bb, const std::string& name) { + return new FCmpInst(fle, v1, v2, bb, name); } -FCmpInst *FCmpInst::create_flt(Value *v1, Value *v2, BasicBlock *bb) { - return new FCmpInst(flt, v1, v2, bb); +FCmpInst *FCmpInst::create_flt(Value *v1, Value *v2, BasicBlock *bb, const std::string& name) { + return new FCmpInst(flt, v1, v2, bb, name); } -FCmpInst *FCmpInst::create_feq(Value *v1, Value *v2, BasicBlock *bb) { - return new FCmpInst(feq, v1, v2, bb); +FCmpInst *FCmpInst::create_feq(Value *v1, Value *v2, BasicBlock *bb, const std::string& name) { + return new FCmpInst(feq, v1, v2, bb, name); } -FCmpInst *FCmpInst::create_fne(Value *v1, Value *v2, BasicBlock *bb) { - return new FCmpInst(fne, v1, v2, bb); +FCmpInst *FCmpInst::create_fne(Value *v1, Value *v2, BasicBlock *bb, const std::string& name) { + return new FCmpInst(fne, v1, v2, bb, name); } -CallInst::CallInst(Function *func, const std::vector& args, BasicBlock *bb) - : Instruction(func->get_return_type(), call, bb) { +CallInst::CallInst(Function *func, const std::vector& args, BasicBlock *bb, const std::string& name) + : Instruction(func->get_return_type(), call, name, bb) { assert(func->get_type()->is_function_type() && "Not a function"); assert((func->get_num_of_args() == args.size()) && "Wrong number of args"); add_operand(func); @@ -137,8 +141,8 @@ CallInst::CallInst(Function *func, const std::vector& args, BasicBlock } CallInst *CallInst::create_call(Function *func, const std::vector& args, - BasicBlock *bb) { - return new CallInst(func, args, bb); + BasicBlock *bb, const std::string& name) { + return new CallInst(func, args, bb, name); } FunctionType *CallInst::get_function_type() const { @@ -147,7 +151,7 @@ FunctionType *CallInst::get_function_type() const { BranchInst::BranchInst(Value *cond, BasicBlock *if_true, BasicBlock *if_false, BasicBlock *bb) - : Instruction(bb->get_module()->get_void_type(), br, bb) { + : Instruction(bb->get_module()->get_void_type(), br, "", bb) { if (cond == nullptr) { // conditionless jump assert(if_false == nullptr && "Given false-bb on conditionless jump"); add_operand(if_true); @@ -194,7 +198,7 @@ BranchInst *BranchInst::create_br(BasicBlock *if_true, BasicBlock *bb) { } ReturnInst::ReturnInst(Value *val, BasicBlock *bb) - : Instruction(bb->get_module()->get_void_type(), ret, bb) { + : Instruction(bb->get_module()->get_void_type(), ret, "", bb) { if (val == nullptr) { assert(bb->get_parent()->get_return_type()->is_void_type()); } else { @@ -216,9 +220,9 @@ ReturnInst *ReturnInst::create_void_ret(BasicBlock *bb) { bool ReturnInst::is_void_ret() const { return get_num_operand() == 0; } GetElementPtrInst::GetElementPtrInst(Value *ptr, const std::vector& idxs, - BasicBlock *bb) + BasicBlock *bb, const std::string& name) : Instruction(PointerType::get(get_element_type(ptr, idxs)), - getelementptr, bb) { + getelementptr, name, bb) { add_operand(ptr); for (auto idx : idxs) { @@ -228,7 +232,7 @@ GetElementPtrInst::GetElementPtrInst(Value *ptr, const std::vector& idx } Type *GetElementPtrInst::get_element_type(const Value *ptr, - const std::vector& idxs) { + const std::vector& idxs, const std::string& name) { assert(ptr->get_type()->is_pointer_type() && "GetElementPtrInst ptr is not a pointer"); @@ -257,12 +261,12 @@ Type *GetElementPtrInst::get_element_type() const { GetElementPtrInst *GetElementPtrInst::create_gep(Value *ptr, const std::vector& idxs, - BasicBlock *bb) { - return new GetElementPtrInst(ptr, idxs, bb); + BasicBlock *bb, const std::string& name) { + return new GetElementPtrInst(ptr, idxs, bb, name); } StoreInst::StoreInst(Value *val, Value *ptr, BasicBlock *bb) - : Instruction(bb->get_module()->get_void_type(), store, bb) { + : Instruction(bb->get_module()->get_void_type(), store, "", bb) { assert((ptr->get_type()->get_pointer_element_type() == val->get_type()) && "StoreInst ptr is not a pointer to val type"); add_operand(val); @@ -273,8 +277,8 @@ StoreInst *StoreInst::create_store(Value *val, Value *ptr, BasicBlock *bb) { return new StoreInst(val, ptr, bb); } -LoadInst::LoadInst(Value *ptr, BasicBlock *bb) - : Instruction(ptr->get_type()->get_pointer_element_type(), load, +LoadInst::LoadInst(Value *ptr, BasicBlock *bb, const std::string& name) + : Instruction(ptr->get_type()->get_pointer_element_type(), load, name, bb) { assert((get_type()->is_integer_type() or get_type()->is_float_type() or get_type()->is_pointer_type()) && @@ -282,12 +286,12 @@ LoadInst::LoadInst(Value *ptr, BasicBlock *bb) add_operand(ptr); } -LoadInst *LoadInst::create_load(Value *ptr, BasicBlock *bb) { - return new LoadInst(ptr, bb); +LoadInst *LoadInst::create_load(Value *ptr, BasicBlock *bb, const std::string& name) { + return new LoadInst(ptr, bb, name); } -AllocaInst::AllocaInst(Type *ty, BasicBlock *bb) - : Instruction(PointerType::get(ty), alloca, bb) { +AllocaInst::AllocaInst(Type *ty, BasicBlock *bb, const std::string& name) + : Instruction(PointerType::get(ty), alloca, name, bb) { static constexpr std::array allowed_alloc_type = { Type::IntegerTyID, Type::FloatTyID, Type::ArrayTyID, Type::PointerTyID}; assert(std::find(allowed_alloc_type.begin(), allowed_alloc_type.end(), @@ -295,12 +299,12 @@ AllocaInst::AllocaInst(Type *ty, BasicBlock *bb) "Not allowed type for alloca"); } -AllocaInst *AllocaInst::create_alloca(Type *ty, BasicBlock *bb) { - return new AllocaInst(ty, bb); +AllocaInst *AllocaInst::create_alloca(Type *ty, BasicBlock *bb, const std::string& name) { + return new AllocaInst(ty, bb, name); } -ZextInst::ZextInst(Value *val, Type *ty, BasicBlock *bb) - : Instruction(ty, zext, bb) { +ZextInst::ZextInst(Value *val, Type *ty, BasicBlock *bb, const std::string& name) + : Instruction(ty, zext, name, bb) { assert(val->get_type()->is_integer_type() && "ZextInst operand is not integer"); assert(ty->is_integer_type() && "ZextInst destination type is not integer"); @@ -311,15 +315,15 @@ ZextInst::ZextInst(Value *val, Type *ty, BasicBlock *bb) add_operand(val); } -ZextInst *ZextInst::create_zext(Value *val, Type *ty, BasicBlock *bb) { - return new ZextInst(val, ty, bb); +ZextInst *ZextInst::create_zext(Value *val, Type *ty, BasicBlock *bb, const std::string& name) { + return new ZextInst(val, ty, bb, name); } -ZextInst *ZextInst::create_zext_to_i32(Value *val, BasicBlock *bb) { - return new ZextInst(val, bb->get_module()->get_int32_type(), bb); +ZextInst *ZextInst::create_zext_to_i32(Value *val, BasicBlock *bb, const std::string& name) { + return new ZextInst(val, bb->get_module()->get_int32_type(), bb, name); } -FpToSiInst::FpToSiInst(Value *val, Type *ty, BasicBlock *bb) - : Instruction(ty, fptosi, bb) { +FpToSiInst::FpToSiInst(Value *val, Type *ty, BasicBlock *bb, const std::string& name) + : Instruction(ty, fptosi, name, bb) { assert(val->get_type()->is_float_type() && "FpToSiInst operand is not float"); assert(ty->is_integer_type() && @@ -327,28 +331,28 @@ FpToSiInst::FpToSiInst(Value *val, Type *ty, BasicBlock *bb) add_operand(val); } -FpToSiInst *FpToSiInst::create_fptosi(Value *val, Type *ty, BasicBlock *bb) { - return new FpToSiInst(val, ty, bb); +FpToSiInst *FpToSiInst::create_fptosi(Value *val, Type *ty, BasicBlock *bb, const std::string& name) { + return new FpToSiInst(val, ty, bb, name); } -FpToSiInst *FpToSiInst::create_fptosi_to_i32(Value *val, BasicBlock *bb) { - return new FpToSiInst(val, bb->get_module()->get_int32_type(), bb); +FpToSiInst *FpToSiInst::create_fptosi_to_i32(Value *val, BasicBlock *bb, const std::string& name) { + return new FpToSiInst(val, bb->get_module()->get_int32_type(), bb, name); } -SiToFpInst::SiToFpInst(Value *val, Type *ty, BasicBlock *bb) - : Instruction(ty, sitofp, bb) { +SiToFpInst::SiToFpInst(Value *val, Type *ty, BasicBlock *bb, const std::string& name) + : Instruction(ty, sitofp, name, bb) { assert(val->get_type()->is_integer_type() && "SiToFpInst operand is not integer"); assert(ty->is_float_type() && "SiToFpInst destination type is not float"); add_operand(val); } -SiToFpInst *SiToFpInst::create_sitofp(Value *val, BasicBlock *bb) { - return new SiToFpInst(val, bb->get_module()->get_float_type(), bb); +SiToFpInst *SiToFpInst::create_sitofp(Value *val, BasicBlock *bb, const std::string& name) { + return new SiToFpInst(val, bb->get_module()->get_float_type(), bb, name); } PhiInst::PhiInst(Type *ty, const std::vector& vals, - const std::vector& val_bbs, BasicBlock *bb) - : Instruction(ty, phi) { + const std::vector& val_bbs, BasicBlock *bb, const std::string& name) + : Instruction(ty, phi, name) { assert(vals.size() == val_bbs.size() && "Unmatched vals and bbs"); for (unsigned i = 0; i < vals.size(); i++) { assert(ty == vals[i]->get_type() && "Bad type for phi"); @@ -360,6 +364,8 @@ PhiInst::PhiInst(Type *ty, const std::vector& vals, PhiInst *PhiInst::create_phi(Type *ty, BasicBlock *bb, const std::vector& vals, - const std::vector& val_bbs) { - return new PhiInst(ty, vals, val_bbs, bb); + const std::vector& val_bbs, const std::string& name) { + return new PhiInst(ty, vals, val_bbs, bb, name); } + +Names GLOBAL_INSTRUCTION_NAMES_{ true, "op", "" }; \ No newline at end of file diff --git a/src/lightir/Names.cpp b/src/lightir/Names.cpp new file mode 100644 index 0000000000000000000000000000000000000000..42174fe6748f61c15c86f163e1075ecbea67da65 --- /dev/null +++ b/src/lightir/Names.cpp @@ -0,0 +1,26 @@ +#include "Names.hpp" + +std::string Names::get_name(std::string name) +{ + int ed = static_cast(name.size()); + while (ed > 0) + { + char ch = name[ed - 1]; + if ((use_underline_ && ch == '_') || (ch >= '0' && ch <= '9')) ed--; + else break; + } + if (ed == 0) return get_name(); + std::string name1 = {name.begin(), name.begin() + ed}; + if (name1 == default_prefix_) return get_name(); + auto get = appended_prefix_ + name1; + auto idx = allocated_[name1]++; + if (idx == 0) return get; + if (use_underline_) get += "_"; + return get + std::to_string(idx); +} + +std::string Names::get_name() +{ + auto get = appended_prefix_ + default_prefix_; + return get + std::to_string(++default_prefix_used_count_); +}