Commit e547371b authored by Yang's avatar Yang

add codegen summary

parent c396901a
...@@ -3,15 +3,15 @@ ...@@ -3,15 +3,15 @@
{ {
"type": "lldb", "type": "lldb",
"request": "launch", "request": "launch",
"name": "Compile & Debug 1.ll", "name": "Compile & Gen 1.ll",
// 要调试的程序 // 要调试的程序
"program": "${workspaceFolder}/build/cminusfc", "program": "${workspaceFolder}/build/cminusfc",
// 命令行参数 // 命令行参数
"args": [ "args": [
"-o",
"./build/1.ll",
"-emit-llvm", "-emit-llvm",
"./build/1.cminus" "./build/1.cminus",
"-o",
"./build/1.ll"
], ],
// 程序运行的目录 // 程序运行的目录
"cwd": "${workspaceFolder}", "cwd": "${workspaceFolder}",
...@@ -24,21 +24,42 @@ ...@@ -24,21 +24,42 @@
{ {
"type": "lldb", "type": "lldb",
"request": "launch", "request": "launch",
"name": "Debug 1.ll", "name": "Gen 1.ll",
// 要调试的程序 // 要调试的程序
"program": "${workspaceFolder}/build/cminusfc", "program": "${workspaceFolder}/build/cminusfc",
// 命令行参数 // 命令行参数
"args": [ "args": [
"-o",
"./build/1.ll",
"-emit-llvm", "-emit-llvm",
"./build/1.cminus" "./build/1.cminus",
"-o",
"./build/1.ll"
], ],
// 程序运行的目录 // 程序运行的目录
"cwd": "${workspaceFolder}", "cwd": "${workspaceFolder}",
"initCommands": [ "initCommands": [
"command script import ${workspaceFolder}/lldb_formatters.py" "command script import ${workspaceFolder}/lldb_formatters.py"
] ]
},
{
"type": "lldb",
"request": "launch",
"name": "Compile & Gen 1.s",
// 要调试的程序
"program": "${workspaceFolder}/build/cminusfc",
// 命令行参数
"args": [
"-S",
"./build/1.cminus",
"-o",
"./build/1.s"
],
// 程序运行的目录
"cwd": "${workspaceFolder}",
// 程序运行前运行的命令(例如 build)
"preLaunchTask": "make cminusfc",
"initCommands": [
"command script import ${workspaceFolder}/lldb_formatters.py"
]
} }
] ]
} }
\ No newline at end of file
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include <string> #include <string>
struct ASMInstruction { struct ASMInstruction {
enum InstType { Instruction, Atrribute, Label, Comment } type; enum InstType { Instruction, Attribute, Label, Comment } type;
std::string content; std::string content;
explicit ASMInstruction(std::string s, InstType ty = Instruction) explicit ASMInstruction(std::string s, InstType ty = Instruction)
...@@ -13,7 +13,7 @@ struct ASMInstruction { ...@@ -13,7 +13,7 @@ struct ASMInstruction {
std::string format() const { std::string format() const {
switch (type) { switch (type) {
case ASMInstruction::Instruction: case ASMInstruction::Instruction:
case ASMInstruction::Atrribute: case ASMInstruction::Attribute:
return "\t" + content + "\n"; return "\t" + content + "\n";
case ASMInstruction::Label: case ASMInstruction::Label:
return content + ":\n"; return content + ":\n";
...@@ -22,4 +22,7 @@ struct ASMInstruction { ...@@ -22,4 +22,7 @@ struct ASMInstruction {
} }
assert(false && "unreachable"); assert(false && "unreachable");
} }
// 用于 lldb 调试生成 summary
std::string safe_print() const;
}; };
...@@ -8,13 +8,16 @@ ...@@ -8,13 +8,16 @@
class CodeGen { class CodeGen {
public: public:
explicit CodeGen(Module *module) : m(module) {} explicit CodeGen(Module *module) : m(module) {}
~CodeGen(){
for(auto i : output) delete i;
}
std::string print() const; std::string print() const;
void run(); void run();
template <class... Args> void append_inst(Args... arg) { template <class... Args> void append_inst(Args... arg) {
output.emplace_back(arg...); output.emplace_back(new ASMInstruction(arg...));
} }
void void
...@@ -26,7 +29,7 @@ class CodeGen { ...@@ -26,7 +29,7 @@ class CodeGen {
} }
content.pop_back(); content.pop_back();
content.pop_back(); content.pop_back();
output.emplace_back(content, ty); output.emplace_back(new ASMInstruction(content, ty));
} }
private: private:
...@@ -98,5 +101,5 @@ class CodeGen { ...@@ -98,5 +101,5 @@ class CodeGen {
} context; } context;
Module *m; Module *m;
std::list<ASMInstruction> output; std::list<ASMInstruction*> output;
}; };
...@@ -32,6 +32,9 @@ struct Reg { ...@@ -32,6 +32,9 @@ struct Reg {
std::string print() const; std::string print() const;
// 用于 lldb 调试生成 summary
std::string safe_print() const;
static Reg zero() { return Reg(0); } static Reg zero() { return Reg(0); }
static Reg ra() { return Reg(1); } static Reg ra() { return Reg(1); }
static Reg sp() { return Reg(3); } static Reg sp() { return Reg(3); }
...@@ -62,17 +65,20 @@ struct FReg { ...@@ -62,17 +65,20 @@ struct FReg {
std::string print() const; std::string print() const;
static FReg fa(unsigned i) { static FReg fa(unsigned i) {
assert(0 <= i and i <= 7); assert(i <= 7);
return FReg(i); return FReg(i);
} }
static FReg ft(unsigned i) { static FReg ft(unsigned i) {
assert(0 <= i and i <= 15); assert(i <= 15);
return FReg(i + 8); return FReg(i + 8);
} }
static FReg fs(unsigned i) { static FReg fs(unsigned i) {
assert(0 <= i and i <= 7); assert(i <= 7);
return FReg(i + 24); return FReg(i + 24);
} }
// 用于 lldb 调试生成 summary
std::string safe_print() const;
}; };
struct CFReg { struct CFReg {
...@@ -82,4 +88,7 @@ struct CFReg { ...@@ -82,4 +88,7 @@ struct CFReg {
bool operator==(const CFReg &other) { return id == other.id; } bool operator==(const CFReg &other) { return id == other.id; }
std::string print() const { return "$fcc" + std::to_string(id); } std::string print() const { return "$fcc" + std::to_string(id); }
// 用于 lldb 调试生成 summary
std::string safe_print() const;
}; };
...@@ -40,7 +40,7 @@ class Function : public Value { ...@@ -40,7 +40,7 @@ class Function : public Value {
BasicBlock *get_entry_block() const { return basic_blocks_.front(); } BasicBlock *get_entry_block() const { return basic_blocks_.front(); }
std::list<BasicBlock*> &get_basic_blocks() { return basic_blocks_; } std::list<BasicBlock*> &get_basic_blocks() { return basic_blocks_; }
std::list<Argument> &get_args() { return arguments_; } std::list<Argument*> &get_args() { return arguments_; }
bool is_declaration() const { return basic_blocks_.empty(); } bool is_declaration() const { return basic_blocks_.empty(); }
...@@ -58,7 +58,7 @@ class Function : public Value { ...@@ -58,7 +58,7 @@ class Function : public Value {
private: private:
std::list<BasicBlock*> basic_blocks_; std::list<BasicBlock*> basic_blocks_;
std::list<Argument> arguments_; std::list<Argument*> arguments_;
Module *parent_; Module *parent_;
unsigned seq_cnt_; // print use unsigned seq_cnt_; // print use
}; };
......
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
class Names class Names
{ {
public: public:
explicit Names(bool use_underline, std::string prefix, std::string append) explicit Names(std::string prefix, std::string append)
: use_underline_(use_underline), default_prefix_used_count_(0), default_prefix_(std::move(prefix)), : default_prefix_used_count_(0), default_prefix_(std::move(prefix)),
appended_prefix_(std::move(append)) appended_prefix_(std::move(append))
{ {
} }
...@@ -18,7 +18,6 @@ public: ...@@ -18,7 +18,6 @@ public:
std::string get_name(); std::string get_name();
private: private:
bool use_underline_;
int default_prefix_used_count_; int default_prefix_used_count_;
std::string default_prefix_; std::string default_prefix_;
std::string appended_prefix_; std::string appended_prefix_;
......
...@@ -9,7 +9,13 @@ def parseString(val : lldb.SBValue): ...@@ -9,7 +9,13 @@ def parseString(val : lldb.SBValue):
return "" return ""
def SafePrintSummary(valobj: lldb.SBValue, internal_dict): def SafePrintSummary(valobj: lldb.SBValue, internal_dict):
name: lldb.SBValue = valobj.EvaluateExpression("this->safe_print()") if valobj.GetType().IsPointerType():
deref: lldb.SBValue = valobj.Dereference()
if deref.IsValid():
valobj = deref
else:
return ""
name: lldb.SBValue = valobj.EvaluateExpression("safe_print()")
return parseString(name) return parseString(name)
def __lldb_init_module(debugger: lldb.SBDebugger, internal_dict): def __lldb_init_module(debugger: lldb.SBDebugger, internal_dict):
...@@ -18,7 +24,8 @@ def __lldb_init_module(debugger: lldb.SBDebugger, internal_dict): ...@@ -18,7 +24,8 @@ def __lldb_init_module(debugger: lldb.SBDebugger, internal_dict):
, "Function", "Argument" , "Function", "Argument"
, "BasicBlock" , "BasicBlock"
, "GlobalVariable" , "GlobalVariable"
, "Instruction", "IBinaryInst", "FBinaryInst", "ICmpInst", "FCmpInst", "CallInst", "BranchInst", "ReturnInst", "GetElementPtrInst", "StoreInst", "LoadInst", "AllocaInst", "ZextInst", "FpToSiInst", "SiToFpInst", "PhiInst" ] , "Instruction", "IBinaryInst", "FBinaryInst", "ICmpInst", "FCmpInst", "CallInst", "BranchInst", "ReturnInst", "GetElementPtrInst", "StoreInst", "LoadInst", "AllocaInst", "ZextInst", "FpToSiInst", "SiToFpInst", "PhiInst"
, "ASMInstruction", "Reg", "FReg", "CFReg" ]
for i in types: for i in types:
debugger.HandleCommand( debugger.HandleCommand(
f"type summary add -F lldb_formatters.SafePrintSummary {i} -w my" f"type summary add -F lldb_formatters.SafePrintSummary {i} -w my"
......
...@@ -142,8 +142,8 @@ Value* CminusfBuilder::visit(ASTFunDeclaration &node) { ...@@ -142,8 +142,8 @@ Value* CminusfBuilder::visit(ASTFunDeclaration &node) {
scope.enter(); scope.enter();
context.pre_enter_scope = true; context.pre_enter_scope = true;
std::vector<Value *> args; std::vector<Value *> args;
for (auto &arg : func->get_args()) { for (auto arg : func->get_args()) {
args.push_back(&arg); args.push_back(arg);
} }
for (unsigned int i = 0; i < node.params.size(); ++i) { for (unsigned int i = 0; i < node.params.size(); ++i) {
if (node.params[i]->isarray) { if (node.params[i]->isarray) {
......
#include "CodeGen.hpp" #include "CodeGen.hpp"
#include "ASMInstruction.hpp"
#include "CodeGenUtil.hpp" #include "CodeGenUtil.hpp"
#include "Register.hpp"
std::string ASMInstruction::safe_print() const
{
switch (type) {
case Instruction:
case Attribute:
return content;
case Label:
return content + ":";
case Comment:
return "# " + content;
}
return "<error>";
}
void CodeGen::allocate() { void CodeGen::allocate() {
// 备份 $ra $fp // 备份 $ra $fp
...@@ -8,9 +24,9 @@ void CodeGen::allocate() { ...@@ -8,9 +24,9 @@ void CodeGen::allocate() {
// 为每个参数分配栈空间 // 为每个参数分配栈空间
for (auto &arg : context.func->get_args()) { for (auto &arg : context.func->get_args()) {
auto size = arg.get_type()->get_size(); auto size = arg->get_type()->get_size();
offset = offset + size; offset = offset + size;
context.offset_map[&arg] = -static_cast<int>(offset); context.offset_map[arg] = -static_cast<int>(offset);
} }
// 为指令结果分配栈空间 // 为指令结果分配栈空间
...@@ -205,11 +221,11 @@ void CodeGen::gen_prologue() { ...@@ -205,11 +221,11 @@ void CodeGen::gen_prologue() {
int garg_cnt = 0; int garg_cnt = 0;
int farg_cnt = 0; int farg_cnt = 0;
for (auto &arg : context.func->get_args()) { for (auto arg : context.func->get_args()) {
if (arg.get_type()->is_float_type()) { if (arg->get_type()->is_float_type()) {
store_from_freg(&arg, FReg::fa(farg_cnt++)); store_from_freg(arg, FReg::fa(farg_cnt++));
} else { // int or pointer } else { // int or pointer
store_from_greg(&arg, Reg::a(garg_cnt++)); store_from_greg(arg, Reg::a(garg_cnt++));
} }
} }
} }
...@@ -241,16 +257,16 @@ void CodeGen::gen_binary() { ...@@ -241,16 +257,16 @@ void CodeGen::gen_binary() {
load_to_greg(context.inst->get_operand(1), Reg::t(1)); load_to_greg(context.inst->get_operand(1), Reg::t(1));
switch (context.inst->get_instr_type()) { switch (context.inst->get_instr_type()) {
case Instruction::add: case Instruction::add:
output.emplace_back("add.w $t2, $t0, $t1"); append_inst("add.w $t2, $t0, $t1");
break; break;
case Instruction::sub: case Instruction::sub:
output.emplace_back("sub.w $t2, $t0, $t1"); append_inst("sub.w $t2, $t0, $t1");
break; break;
case Instruction::mul: case Instruction::mul:
output.emplace_back("mul.w $t2, $t0, $t1"); append_inst("mul.w $t2, $t0, $t1");
break; break;
case Instruction::sdiv: case Instruction::sdiv:
output.emplace_back("div.w $t2, $t0, $t1"); append_inst("div.w $t2, $t0, $t1");
break; break;
default: default:
assert(false); assert(false);
...@@ -370,26 +386,26 @@ void CodeGen::run() { ...@@ -370,26 +386,26 @@ void CodeGen::run() {
* - 支持更旧版本的 GNU 汇编器, 因为 `.bss` 伪指令是应该相对较新的指令, * - 支持更旧版本的 GNU 汇编器, 因为 `.bss` 伪指令是应该相对较新的指令,
* GNU 汇编器在 2023 年 2 月的 2.37 版本才将其引入 * GNU 汇编器在 2023 年 2 月的 2.37 版本才将其引入
*/ */
append_inst(".text", ASMInstruction::Atrribute); append_inst(".text", ASMInstruction::Attribute);
append_inst(".section", {".bss", "\"aw\"", "@nobits"}, append_inst(".section", {".bss", "\"aw\"", "@nobits"},
ASMInstruction::Atrribute); ASMInstruction::Attribute);
for (auto global : m->get_global_variable()) { for (auto global : m->get_global_variable()) {
auto size = auto size =
global->get_type()->get_pointer_element_type()->get_size(); global->get_type()->get_pointer_element_type()->get_size();
append_inst(".globl", {global->get_name()}, append_inst(".globl", {global->get_name()},
ASMInstruction::Atrribute); ASMInstruction::Attribute);
append_inst(".type", {global->get_name(), "@object"}, append_inst(".type", {global->get_name(), "@object"},
ASMInstruction::Atrribute); ASMInstruction::Attribute);
append_inst(".size", {global->get_name(), std::to_string(size)}, append_inst(".size", {global->get_name(), std::to_string(size)},
ASMInstruction::Atrribute); ASMInstruction::Attribute);
append_inst(global->get_name(), ASMInstruction::Label); append_inst(global->get_name(), ASMInstruction::Label);
append_inst(".space", {std::to_string(size)}, append_inst(".space", {std::to_string(size)},
ASMInstruction::Atrribute); ASMInstruction::Attribute);
} }
} }
// 函数代码段 // 函数代码段
output.emplace_back(".text", ASMInstruction::Atrribute); output.emplace_back(new ASMInstruction(".text", ASMInstruction::Attribute));
for (auto func : m->get_functions()) { for (auto func : m->get_functions()) {
if (not func->is_declaration()) { if (not func->is_declaration()) {
// 更新 context // 更新 context
...@@ -397,9 +413,9 @@ void CodeGen::run() { ...@@ -397,9 +413,9 @@ void CodeGen::run() {
context.func = func; context.func = func;
// 函数信息 // 函数信息
append_inst(".globl", {func->get_name()}, ASMInstruction::Atrribute); append_inst(".globl", {func->get_name()}, ASMInstruction::Attribute);
append_inst(".type", {func->get_name(), "@function"}, append_inst(".type", {func->get_name(), "@function"},
ASMInstruction::Atrribute); ASMInstruction::Attribute);
append_inst(func->get_name(), ASMInstruction::Label); append_inst(func->get_name(), ASMInstruction::Label);
// 分配函数栈帧 // 分配函数栈帧
...@@ -495,8 +511,8 @@ void CodeGen::run() { ...@@ -495,8 +511,8 @@ void CodeGen::run() {
std::string CodeGen::print() const { std::string CodeGen::print() const {
std::string result; std::string result;
for (const auto &inst : output) { for (const auto inst : output) {
result += inst.format(); result += inst->format();
} }
return result; return result;
} }
...@@ -26,9 +26,35 @@ std::string Reg::print() const { ...@@ -26,9 +26,35 @@ std::string Reg::print() const {
assert(false); assert(false);
} }
std::string Reg::safe_print() const
{
if (id == 0) {
return "$zero";
}
if (id == 1) {
return "$ra";
}
if (id == 2) {
return "$tp";
}
if (id == 3) {
return "$sp";
}
if (4 <= id and id <= 11) {
return "$a" + std::to_string(id - 4);
}
if (12 <= id and id <= 20) {
return "$t" + std::to_string(id - 12);
}
if (id == 22) {
return "$fp";
}
return "<error id " + std::to_string(id) + ">";
}
std::string FReg::print() const { std::string FReg::print() const {
if (0 <= id and id <= 7) { if (id <= 7) {
return "$fa" + std::to_string(id); return "$fa" + std::to_string(id);
} }
if (8 <= id and id <= 23) { if (8 <= id and id <= 23) {
...@@ -39,3 +65,22 @@ std::string FReg::print() const { ...@@ -39,3 +65,22 @@ std::string FReg::print() const {
} }
assert(false); assert(false);
} }
std::string FReg::safe_print() const
{
if (id <= 7) {
return "$fa" + std::to_string(id);
}
if (8 <= id and id <= 23) {
return "$ft" + std::to_string(id - 8);
}
if (24 <= id and id <= 31) {
return "$fs" + std::to_string(id - 24);
}
return "<error id " + std::to_string(id) + ">";
}
std::string CFReg::safe_print() const
{
return "$fcc" + std::to_string(id);
}
...@@ -125,4 +125,4 @@ BasicBlock* BasicBlock::get_entry_block_of_same_function() const ...@@ -125,4 +125,4 @@ BasicBlock* BasicBlock::get_entry_block_of_same_function() const
return parent_->get_entry_block(); return parent_->get_entry_block();
} }
Names GLOBAL_BASICBLOCK_NAMES_{false, "label", ""}; Names GLOBAL_BASICBLOCK_NAMES_{"label", "_"};
\ No newline at end of file \ No newline at end of file
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include "Module.hpp" #include "Module.hpp"
#include "Instruction.hpp" #include "Instruction.hpp"
#include <cassert> #include <cassert>
#include <string>
#include <unordered_set> #include <unordered_set>
#include <queue> #include <queue>
...@@ -10,24 +11,25 @@ namespace ...@@ -10,24 +11,25 @@ namespace
{ {
std::string chopName(std::string name) std::string chopName(std::string name)
{ {
if (name.size() > 4) return { name.begin(), name.begin() + 4 }; if (name.size() > 3) return { name.begin(), name.begin() + 3 };
return name; return name;
} }
} }
Function::Function(FunctionType* ty, const std::string& name, Module* parent) Function::Function(FunctionType* ty, const std::string& name, Module* parent)
: Value(ty, name), names4blocks_(false, "label", chopName(name)), names4insts_(true, "op", ""), parent_(parent), seq_cnt_(0) { : Value(ty, name), names4blocks_("label", chopName(name) + "_"), names4insts_("op", ""), parent_(parent), seq_cnt_(0) {
// num_args_ = ty->getNumParams(); // num_args_ = ty->getNumParams();
parent->add_function(this); parent->add_function(this);
// build args // build args
for (unsigned i = 0; i < get_num_of_args(); i++) { for (unsigned i = 0; i < get_num_of_args(); i++) {
arguments_.emplace_back(ty->get_param_type(i), "", this, i); arguments_.emplace_back(new Argument(ty->get_param_type(i), "arg" + std::to_string(i), this, i));
} }
} }
Function::~Function() Function::~Function()
{ {
for (auto bb : basic_blocks_) delete bb; for (auto bb : basic_blocks_) delete bb;
for(auto arg: arguments_) delete arg;
} }
Function* Function::create(FunctionType* ty, const std::string& name, Function* Function::create(FunctionType* ty, const std::string& name,
...@@ -66,10 +68,10 @@ void Function::add_basic_block(BasicBlock* bb) { basic_blocks_.push_back(bb); } ...@@ -66,10 +68,10 @@ void Function::add_basic_block(BasicBlock* bb) { basic_blocks_.push_back(bb); }
void Function::set_instr_name() { void Function::set_instr_name() {
std::map<Value*, int> seq; std::map<Value*, int> seq;
for (auto& arg : this->get_args()) { for (auto& arg : this->get_args()) {
if (seq.find(&arg) == seq.end()) { if (seq.find(arg) == seq.end()) {
auto seq_num = seq.size() + seq_cnt_; auto seq_num = seq.size() + seq_cnt_;
if (arg.set_name("arg" + std::to_string(seq_num))) { if (arg->set_name("arg" + std::to_string(seq_num))) {
seq.insert({ &arg, seq_num }); seq.insert({ arg, seq_num });
} }
} }
} }
...@@ -121,7 +123,7 @@ std::string Function::print() { ...@@ -121,7 +123,7 @@ std::string Function::print() {
for (auto& arg : get_args()) { for (auto& arg : get_args()) {
if (&arg != &*get_args().begin()) if (&arg != &*get_args().begin())
func_ir += ", "; func_ir += ", ";
func_ir += arg.print(); func_ir += arg->print();
} }
} }
func_ir += ")"; func_ir += ")";
...@@ -160,7 +162,7 @@ std::string Argument::safe_print() const ...@@ -160,7 +162,7 @@ std::string Argument::safe_print() const
auto ty = parent->get_function_type(); auto ty = parent->get_function_type();
if (ty == nullptr || ty->get_num_of_args() <= arg_no_) return "@" + parent->get_name() + " arg" + std::to_string(arg_no_) + " <unknow type>"; if (ty == nullptr || ty->get_num_of_args() <= arg_no_) return "@" + parent->get_name() + " arg" + std::to_string(arg_no_) + " <unknow type>";
auto ty2 = ty->get_param_type(arg_no_); auto ty2 = ty->get_param_type(arg_no_);
return "@" + parent->get_name() + " arg" + std::to_string(arg_no_) + " " + (ty2 == nullptr ? "<null>" : ty2->safe_print()); return (ty2 == nullptr ? "<null>" : ty2->safe_print()) + " @" + parent->get_name() + " arg" + std::to_string(arg_no_);
} }
......
...@@ -538,10 +538,12 @@ std::string BranchInst::print() { ...@@ -538,10 +538,12 @@ std::string BranchInst::print() {
std::string ReturnInst::print() { std::string ReturnInst::print() {
std::string instr_ir; std::string instr_ir;
instr_ir += safe_print_instr_op_name(get_instr_type()); instr_ir += get_instr_op_name();
instr_ir += " "; instr_ir += " ";
if (!is_void_ret()) { if (!is_void_ret()) {
instr_ir += safe_print_op_as_op(this, 0, true); instr_ir += this->get_operand(0)->get_type()->print();
instr_ir += " ";
instr_ir += print_as_op(this->get_operand(0), false);
} else { } else {
instr_ir += "void"; instr_ir += "void";
} }
......
...@@ -368,4 +368,4 @@ PhiInst *PhiInst::create_phi(Type *ty, BasicBlock *bb, ...@@ -368,4 +368,4 @@ PhiInst *PhiInst::create_phi(Type *ty, BasicBlock *bb,
return new PhiInst(ty, vals, val_bbs, bb, name); return new PhiInst(ty, vals, val_bbs, bb, name);
} }
Names GLOBAL_INSTRUCTION_NAMES_{ true, "op", "" }; Names GLOBAL_INSTRUCTION_NAMES_{"op", "_" };
\ No newline at end of file \ No newline at end of file
...@@ -3,19 +3,25 @@ ...@@ -3,19 +3,25 @@
std::string Names::get_name(std::string name) std::string Names::get_name(std::string name)
{ {
int ed = static_cast<int>(name.size()); int ed = static_cast<int>(name.size());
while (ed > 0) int bg = 0;
while (bg < ed)
{
char ch = name[bg];
if (ch == '_' || (ch >= '0' && ch <= '9')) bg++;
else break;
}
while (ed > bg)
{ {
char ch = name[ed - 1]; char ch = name[ed - 1];
if ((use_underline_ && ch == '_') || (ch >= '0' && ch <= '9')) ed--; if (ch == '_' || (ch >= '0' && ch <= '9')) ed--;
else break; else break;
} }
if (ed == 0) return get_name(); if (bg == ed) return get_name();
std::string name1 = {name.begin(), name.begin() + ed}; std::string name1 = {name.begin() + bg, name.begin() + ed};
if (name1 == default_prefix_) return get_name(); if (name1 == default_prefix_) return get_name();
auto get = appended_prefix_ + name1; auto get = appended_prefix_ + name1;
auto idx = allocated_[name1]++; auto idx = allocated_[name1]++;
if (idx == 0) return get; if (idx == 0) return get;
if (use_underline_) get += "_";
return get + std::to_string(idx); return get + std::to_string(idx);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment