refactor(dev): 统一 IR/MIR 接口命名风格

This commit is contained in:
Lane0218
2026-03-12 15:17:02 +08:00
parent f26551a896
commit b1155d8fa9
18 changed files with 170 additions and 167 deletions

View File

@@ -43,7 +43,7 @@ class Type {
public: public:
enum class Kind { Void, Int32, PtrInt32 }; enum class Kind { Void, Int32, PtrInt32 };
explicit Type(Kind k); explicit Type(Kind k);
Kind kind() const; Kind GetKind() const;
bool IsVoid() const; bool IsVoid() const;
bool IsInt32() const; bool IsInt32() const;
bool IsPtrInt32() const; bool IsPtrInt32() const;
@@ -56,11 +56,11 @@ class Value {
public: public:
Value(std::shared_ptr<Type> ty, std::string name); Value(std::shared_ptr<Type> ty, std::string name);
virtual ~Value() = default; virtual ~Value() = default;
const std::shared_ptr<Type>& type() const; const std::shared_ptr<Type>& GetType() const;
const std::string& name() const; const std::string& GetName() const;
void set_name(std::string n); void SetName(std::string n);
void AddUser(Instruction* user); void AddUser(Instruction* user);
const std::vector<Instruction*>& users() const; const std::vector<Instruction*>& GetUsers() const;
protected: protected:
std::shared_ptr<Type> type_; std::shared_ptr<Type> type_;
@@ -71,7 +71,7 @@ class Value {
class ConstantInt : public Value { class ConstantInt : public Value {
public: public:
ConstantInt(std::shared_ptr<Type> ty, int v); ConstantInt(std::shared_ptr<Type> ty, int v);
int value() const { return value_; } int GetValue() const { return value_; }
private: private:
int value_{}; int value_{};
@@ -83,10 +83,10 @@ enum class Opcode { Add, Sub, Mul, Alloca, Load, Store, Ret };
class Instruction : public Value { class Instruction : public Value {
public: public:
Instruction(Opcode op, std::shared_ptr<Type> ty, std::string name = ""); Instruction(Opcode op, std::shared_ptr<Type> ty, std::string name = "");
Opcode opcode() const; Opcode GetOpcode() const;
bool IsTerminator() const; bool IsTerminator() const;
BasicBlock* parent() const; BasicBlock* GetParent() const;
void set_parent(BasicBlock* parent); void SetParent(BasicBlock* parent);
private: private:
Opcode opcode_; Opcode opcode_;
@@ -97,8 +97,8 @@ class BinaryInst : public Instruction {
public: public:
BinaryInst(Opcode op, std::shared_ptr<Type> ty, Value* lhs, Value* rhs, BinaryInst(Opcode op, std::shared_ptr<Type> ty, Value* lhs, Value* rhs,
std::string name); std::string name);
Value* lhs() const; Value* GetLhs() const;
Value* rhs() const; Value* GetRhs() const;
private: private:
Value* lhs_; Value* lhs_;
@@ -108,7 +108,7 @@ class BinaryInst : public Instruction {
class ReturnInst : public Instruction { class ReturnInst : public Instruction {
public: public:
ReturnInst(std::shared_ptr<Type> void_ty, Value* val); ReturnInst(std::shared_ptr<Type> void_ty, Value* val);
Value* value() const; Value* GetValue() const;
private: private:
Value* value_; Value* value_;
@@ -122,7 +122,7 @@ class AllocaInst : public Instruction {
class LoadInst : public Instruction { class LoadInst : public Instruction {
public: public:
LoadInst(std::shared_ptr<Type> val_ty, Value* ptr, std::string name); LoadInst(std::shared_ptr<Type> val_ty, Value* ptr, std::string name);
Value* ptr() const; Value* GetPtr() const;
private: private:
Value* ptr_; Value* ptr_;
@@ -131,8 +131,8 @@ class LoadInst : public Instruction {
class StoreInst : public Instruction { class StoreInst : public Instruction {
public: public:
StoreInst(std::shared_ptr<Type> void_ty, Value* val, Value* ptr); StoreInst(std::shared_ptr<Type> void_ty, Value* val, Value* ptr);
Value* value() const; Value* GetValue() const;
Value* ptr() const; Value* GetPtr() const;
private: private:
Value* value_; Value* value_;
@@ -142,13 +142,13 @@ class StoreInst : public Instruction {
class BasicBlock { class BasicBlock {
public: public:
explicit BasicBlock(std::string name); explicit BasicBlock(std::string name);
const std::string& name() const; const std::string& GetName() const;
Function* parent() const; Function* GetParent() const;
void set_parent(Function* parent); void SetParent(Function* parent);
bool HasTerminator() const; bool HasTerminator() const;
const std::vector<std::unique_ptr<Instruction>>& instructions() const; const std::vector<std::unique_ptr<Instruction>>& GetInstructions() const;
const std::vector<BasicBlock*>& predecessors() const; const std::vector<BasicBlock*>& GetPredecessors() const;
const std::vector<BasicBlock*>& successors() const; const std::vector<BasicBlock*>& GetSuccessors() const;
template <typename T, typename... Args> template <typename T, typename... Args>
T* Append(Args&&... args) { T* Append(Args&&... args) {
if (HasTerminator()) { if (HasTerminator()) {
@@ -157,7 +157,7 @@ class BasicBlock {
} }
auto inst = std::make_unique<T>(std::forward<Args>(args)...); auto inst = std::make_unique<T>(std::forward<Args>(args)...);
auto* ptr = inst.get(); auto* ptr = inst.get();
ptr->set_parent(this); ptr->SetParent(this);
instructions_.push_back(std::move(inst)); instructions_.push_back(std::move(inst));
return ptr; return ptr;
} }
@@ -175,9 +175,9 @@ class Function : public Value {
// 允许显式指定返回类型,便于后续扩展多种函数签名。 // 允许显式指定返回类型,便于后续扩展多种函数签名。
Function(std::string name, std::shared_ptr<Type> ret_type); Function(std::string name, std::shared_ptr<Type> ret_type);
BasicBlock* CreateBlock(const std::string& name); BasicBlock* CreateBlock(const std::string& name);
BasicBlock* entry(); BasicBlock* GetEntry();
const BasicBlock* entry() const; const BasicBlock* GetEntry() const;
const std::vector<std::unique_ptr<BasicBlock>>& blocks() const; const std::vector<std::unique_ptr<BasicBlock>>& GetBlocks() const;
private: private:
BasicBlock* entry_ = nullptr; BasicBlock* entry_ = nullptr;
@@ -187,12 +187,12 @@ class Function : public Value {
class Module { class Module {
public: public:
Module() = default; Module() = default;
Context& context(); Context& GetContext();
const Context& context() const; const Context& GetContext() const;
// 创建函数时显式传入返回类型,便于在 IRGen 中根据语法树信息选择类型。 // 创建函数时显式传入返回类型,便于在 IRGen 中根据语法树信息选择类型。
Function* CreateFunction(const std::string& name, Function* CreateFunction(const std::string& name,
std::shared_ptr<Type> ret_type); std::shared_ptr<Type> ret_type);
const std::vector<std::unique_ptr<Function>>& functions() const; const std::vector<std::unique_ptr<Function>>& GetFunctions() const;
private: private:
Context context_; Context context_;
@@ -217,7 +217,7 @@ class IRBuilder {
private: private:
Context& ctx_; Context& ctx_;
BasicBlock* insertBlock_; BasicBlock* insert_block_;
}; };
class IRPrinter { class IRPrinter {

View File

@@ -41,10 +41,10 @@ class Operand {
static Operand Imm(int value); static Operand Imm(int value);
static Operand FrameIndex(int index); static Operand FrameIndex(int index);
Kind kind() const { return kind_; } Kind GetKind() const { return kind_; }
PhysReg reg() const { return reg_; } PhysReg GetReg() const { return reg_; }
int imm() const { return imm_; } int GetImm() const { return imm_; }
int frame_index() const { return imm_; } int GetFrameIndex() const { return imm_; }
private: private:
Operand(Kind kind, PhysReg reg, int imm); Operand(Kind kind, PhysReg reg, int imm);
@@ -58,8 +58,8 @@ class MachineInstr {
public: public:
MachineInstr(Opcode opcode, std::vector<Operand> operands = {}); MachineInstr(Opcode opcode, std::vector<Operand> operands = {});
Opcode opcode() const { return opcode_; } Opcode GetOpcode() const { return opcode_; }
const std::vector<Operand>& operands() const { return operands_; } const std::vector<Operand>& GetOperands() const { return operands_; }
private: private:
Opcode opcode_; Opcode opcode_;
@@ -76,9 +76,9 @@ class MachineBasicBlock {
public: public:
explicit MachineBasicBlock(std::string name); explicit MachineBasicBlock(std::string name);
const std::string& name() const { return name_; } const std::string& GetName() const { return name_; }
std::vector<MachineInstr>& instructions() { return instructions_; } std::vector<MachineInstr>& GetInstructions() { return instructions_; }
const std::vector<MachineInstr>& instructions() const { return instructions_; } const std::vector<MachineInstr>& GetInstructions() const { return instructions_; }
MachineInstr& Append(Opcode opcode, MachineInstr& Append(Opcode opcode,
std::initializer_list<Operand> operands = {}); std::initializer_list<Operand> operands = {});
@@ -92,17 +92,17 @@ class MachineFunction {
public: public:
explicit MachineFunction(std::string name); explicit MachineFunction(std::string name);
const std::string& name() const { return name_; } const std::string& GetName() const { return name_; }
MachineBasicBlock& entry() { return entry_; } MachineBasicBlock& GetEntry() { return entry_; }
const MachineBasicBlock& entry() const { return entry_; } const MachineBasicBlock& GetEntry() const { return entry_; }
int CreateFrameIndex(int size = 4); int CreateFrameIndex(int size = 4);
FrameSlot& frame_slot(int index); FrameSlot& GetFrameSlot(int index);
const FrameSlot& frame_slot(int index) const; const FrameSlot& GetFrameSlot(int index) const;
const std::vector<FrameSlot>& frame_slots() const { return frame_slots_; } const std::vector<FrameSlot>& GetFrameSlots() const { return frame_slots_; }
int frame_size() const { return frame_size_; } int GetFrameSize() const { return frame_size_; }
void set_frame_size(int size) { frame_size_ = size; } void SetFrameSize(int size) { frame_size_ = size; }
private: private:
std::string name_; std::string name_;

View File

@@ -10,26 +10,26 @@ namespace ir {
BasicBlock::BasicBlock(std::string name) : name_(std::move(name)) {} BasicBlock::BasicBlock(std::string name) : name_(std::move(name)) {}
const std::string& BasicBlock::name() const { return name_; } const std::string& BasicBlock::GetName() const { return name_; }
Function* BasicBlock::parent() const { return parent_; } Function* BasicBlock::GetParent() const { return parent_; }
void BasicBlock::set_parent(Function* parent) { parent_ = parent; } void BasicBlock::SetParent(Function* parent) { parent_ = parent; }
bool BasicBlock::HasTerminator() const { bool BasicBlock::HasTerminator() const {
return !instructions_.empty() && instructions_.back()->IsTerminator(); return !instructions_.empty() && instructions_.back()->IsTerminator();
} }
const std::vector<std::unique_ptr<Instruction>>& BasicBlock::instructions() const std::vector<std::unique_ptr<Instruction>>& BasicBlock::GetInstructions()
const { const {
return instructions_; return instructions_;
} }
const std::vector<BasicBlock*>& BasicBlock::predecessors() const { const std::vector<BasicBlock*>& BasicBlock::GetPredecessors() const {
return predecessors_; return predecessors_;
} }
const std::vector<BasicBlock*>& BasicBlock::successors() const { const std::vector<BasicBlock*>& BasicBlock::GetSuccessors() const {
return successors_; return successors_;
} }

View File

@@ -13,7 +13,7 @@ Function::Function(std::string name, std::shared_ptr<Type> ret_type)
BasicBlock* Function::CreateBlock(const std::string& name) { BasicBlock* Function::CreateBlock(const std::string& name) {
auto block = std::make_unique<BasicBlock>(name); auto block = std::make_unique<BasicBlock>(name);
auto* ptr = block.get(); auto* ptr = block.get();
ptr->set_parent(this); ptr->SetParent(this);
blocks_.push_back(std::move(block)); blocks_.push_back(std::move(block));
if (!entry_) { if (!entry_) {
entry_ = ptr; entry_ = ptr;
@@ -21,11 +21,11 @@ BasicBlock* Function::CreateBlock(const std::string& name) {
return ptr; return ptr;
} }
BasicBlock* Function::entry() { return entry_; } BasicBlock* Function::GetEntry() { return entry_; }
const BasicBlock* Function::entry() const { return entry_; } const BasicBlock* Function::GetEntry() const { return entry_; }
const std::vector<std::unique_ptr<BasicBlock>>& Function::blocks() const { const std::vector<std::unique_ptr<BasicBlock>>& Function::GetBlocks() const {
return blocks_; return blocks_;
} }

View File

@@ -10,11 +10,11 @@
namespace ir { namespace ir {
IRBuilder::IRBuilder(Context& ctx, BasicBlock* bb) IRBuilder::IRBuilder(Context& ctx, BasicBlock* bb)
: ctx_(ctx), insertBlock_(bb) {} : ctx_(ctx), insert_block_(bb) {}
void IRBuilder::SetInsertPoint(BasicBlock* bb) { insertBlock_ = bb; } void IRBuilder::SetInsertPoint(BasicBlock* bb) { insert_block_ = bb; }
BasicBlock* IRBuilder::GetInsertBlock() const { return insertBlock_; } BasicBlock* IRBuilder::GetInsertBlock() const { return insert_block_; }
ConstantInt* IRBuilder::CreateConstInt(int v) { ConstantInt* IRBuilder::CreateConstInt(int v) {
// 常量不需要挂在基本块里,由 Context 负责去重与生命周期。 // 常量不需要挂在基本块里,由 Context 负责去重与生命周期。
@@ -23,7 +23,7 @@ ConstantInt* IRBuilder::CreateConstInt(int v) {
BinaryInst* IRBuilder::CreateBinary(Opcode op, Value* lhs, Value* rhs, BinaryInst* IRBuilder::CreateBinary(Opcode op, Value* lhs, Value* rhs,
const std::string& name) { const std::string& name) {
if (!insertBlock_) { if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
} }
if (!lhs) { if (!lhs) {
@@ -34,7 +34,7 @@ BinaryInst* IRBuilder::CreateBinary(Opcode op, Value* lhs, Value* rhs,
throw std::runtime_error( throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateBinary 缺少 rhs")); FormatError("ir", "IRBuilder::CreateBinary 缺少 rhs"));
} }
return insertBlock_->Append<BinaryInst>(op, lhs->type(), lhs, rhs, name); return insert_block_->Append<BinaryInst>(op, lhs->GetType(), lhs, rhs, name);
} }
BinaryInst* IRBuilder::CreateAdd(Value* lhs, Value* rhs, BinaryInst* IRBuilder::CreateAdd(Value* lhs, Value* rhs,
@@ -43,25 +43,25 @@ BinaryInst* IRBuilder::CreateAdd(Value* lhs, Value* rhs,
} }
AllocaInst* IRBuilder::CreateAllocaI32(const std::string& name) { AllocaInst* IRBuilder::CreateAllocaI32(const std::string& name) {
if (!insertBlock_) { if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
} }
return insertBlock_->Append<AllocaInst>(ctx_.PtrInt32(), name); return insert_block_->Append<AllocaInst>(ctx_.PtrInt32(), name);
} }
LoadInst* IRBuilder::CreateLoad(Value* ptr, const std::string& name) { LoadInst* IRBuilder::CreateLoad(Value* ptr, const std::string& name) {
if (!insertBlock_) { if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
} }
if (!ptr) { if (!ptr) {
throw std::runtime_error( throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateLoad 缺少 ptr")); FormatError("ir", "IRBuilder::CreateLoad 缺少 ptr"));
} }
return insertBlock_->Append<LoadInst>(ctx_.Int32(), ptr, name); return insert_block_->Append<LoadInst>(ctx_.Int32(), ptr, name);
} }
StoreInst* IRBuilder::CreateStore(Value* val, Value* ptr) { StoreInst* IRBuilder::CreateStore(Value* val, Value* ptr) {
if (!insertBlock_) { if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
} }
if (!val) { if (!val) {
@@ -72,18 +72,18 @@ StoreInst* IRBuilder::CreateStore(Value* val, Value* ptr) {
throw std::runtime_error( throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateStore 缺少 ptr")); FormatError("ir", "IRBuilder::CreateStore 缺少 ptr"));
} }
return insertBlock_->Append<StoreInst>(ctx_.Void(), val, ptr); return insert_block_->Append<StoreInst>(ctx_.Void(), val, ptr);
} }
ReturnInst* IRBuilder::CreateRet(Value* v) { ReturnInst* IRBuilder::CreateRet(Value* v) {
if (!insertBlock_) { if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
} }
if (!v) { if (!v) {
throw std::runtime_error( throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateRet 缺少返回值")); FormatError("ir", "IRBuilder::CreateRet 缺少返回值"));
} }
return insertBlock_->Append<ReturnInst>(ctx_.Void(), v); return insert_block_->Append<ReturnInst>(ctx_.Void(), v);
} }
} // namespace ir } // namespace ir

View File

@@ -13,7 +13,7 @@
namespace ir { namespace ir {
static const char* TypeToString(const Type& ty) { static const char* TypeToString(const Type& ty) {
switch (ty.kind()) { switch (ty.GetKind()) {
case Type::Kind::Void: case Type::Kind::Void:
return "void"; return "void";
case Type::Kind::Int32: case Type::Kind::Int32:
@@ -46,54 +46,55 @@ static const char* OpcodeToString(Opcode op) {
static std::string ValueToString(const Value* v) { static std::string ValueToString(const Value* v) {
if (auto* ci = dynamic_cast<const ConstantInt*>(v)) { if (auto* ci = dynamic_cast<const ConstantInt*>(v)) {
return std::to_string(ci->value()); return std::to_string(ci->GetValue());
} }
return v ? v->name() : "<null>"; return v ? v->GetName() : "<null>";
} }
void IRPrinter::Print(const Module& module, std::ostream& os) { void IRPrinter::Print(const Module& module, std::ostream& os) {
for (const auto& func : module.functions()) { for (const auto& func : module.GetFunctions()) {
os << "define " << TypeToString(*func->type()) << " @" << func->name() os << "define " << TypeToString(*func->GetType()) << " @" << func->GetName()
<< "() {\n"; << "() {\n";
for (const auto& bb : func->blocks()) { for (const auto& bb : func->GetBlocks()) {
if (!bb) { if (!bb) {
continue; continue;
} }
os << bb->name() << ":\n"; os << bb->GetName() << ":\n";
for (const auto& instPtr : bb->instructions()) { for (const auto& instPtr : bb->GetInstructions()) {
const auto* inst = instPtr.get(); const auto* inst = instPtr.get();
switch (inst->opcode()) { switch (inst->GetOpcode()) {
case Opcode::Add: case Opcode::Add:
case Opcode::Sub: case Opcode::Sub:
case Opcode::Mul: { case Opcode::Mul: {
auto* bin = static_cast<const BinaryInst*>(inst); auto* bin = static_cast<const BinaryInst*>(inst);
os << " " << bin->name() << " = " << OpcodeToString(bin->opcode()) os << " " << bin->GetName() << " = "
<< " " << TypeToString(*bin->lhs()->type()) << " " << OpcodeToString(bin->GetOpcode()) << " "
<< ValueToString(bin->lhs()) << ", " << TypeToString(*bin->GetLhs()->GetType()) << " "
<< ValueToString(bin->rhs()) << "\n"; << ValueToString(bin->GetLhs()) << ", "
<< ValueToString(bin->GetRhs()) << "\n";
break; break;
} }
case Opcode::Alloca: { case Opcode::Alloca: {
auto* alloca = static_cast<const AllocaInst*>(inst); auto* alloca = static_cast<const AllocaInst*>(inst);
os << " " << alloca->name() << " = alloca i32\n"; os << " " << alloca->GetName() << " = alloca i32\n";
break; break;
} }
case Opcode::Load: { case Opcode::Load: {
auto* load = static_cast<const LoadInst*>(inst); auto* load = static_cast<const LoadInst*>(inst);
os << " " << load->name() << " = load i32, i32* " os << " " << load->GetName() << " = load i32, i32* "
<< ValueToString(load->ptr()) << "\n"; << ValueToString(load->GetPtr()) << "\n";
break; break;
} }
case Opcode::Store: { case Opcode::Store: {
auto* store = static_cast<const StoreInst*>(inst); auto* store = static_cast<const StoreInst*>(inst);
os << " store i32 " << ValueToString(store->value()) << ", i32* " os << " store i32 " << ValueToString(store->GetValue())
<< ValueToString(store->ptr()) << "\n"; << ", i32* " << ValueToString(store->GetPtr()) << "\n";
break; break;
} }
case Opcode::Ret: { case Opcode::Ret: {
auto* ret = static_cast<const ReturnInst*>(inst); auto* ret = static_cast<const ReturnInst*>(inst);
os << " ret " << TypeToString(*ret->value()->type()) << " " os << " ret " << TypeToString(*ret->GetValue()->GetType()) << " "
<< ValueToString(ret->value()) << "\n"; << ValueToString(ret->GetValue()) << "\n";
break; break;
} }
} }

View File

@@ -11,13 +11,13 @@ namespace ir {
Instruction::Instruction(Opcode op, std::shared_ptr<Type> ty, std::string name) Instruction::Instruction(Opcode op, std::shared_ptr<Type> ty, std::string name)
: Value(std::move(ty), std::move(name)), opcode_(op) {} : Value(std::move(ty), std::move(name)), opcode_(op) {}
Opcode Instruction::opcode() const { return opcode_; } Opcode Instruction::GetOpcode() const { return opcode_; }
bool Instruction::IsTerminator() const { return opcode_ == Opcode::Ret; } bool Instruction::IsTerminator() const { return opcode_ == Opcode::Ret; }
BasicBlock* Instruction::parent() const { return parent_; } BasicBlock* Instruction::GetParent() const { return parent_; }
void Instruction::set_parent(BasicBlock* parent) { parent_ = parent; } void Instruction::SetParent(BasicBlock* parent) { parent_ = parent; }
BinaryInst::BinaryInst(Opcode op, std::shared_ptr<Type> ty, Value* lhs, BinaryInst::BinaryInst(Opcode op, std::shared_ptr<Type> ty, Value* lhs,
Value* rhs, std::string name) Value* rhs, std::string name)
@@ -28,11 +28,11 @@ BinaryInst::BinaryInst(Opcode op, std::shared_ptr<Type> ty, Value* lhs,
if (!lhs_ || !rhs_) { if (!lhs_ || !rhs_) {
throw std::runtime_error(FormatError("ir", "BinaryInst 缺少操作数")); throw std::runtime_error(FormatError("ir", "BinaryInst 缺少操作数"));
} }
if (!type_ || !lhs_->type() || !rhs_->type()) { if (!type_ || !lhs_->GetType() || !rhs_->GetType()) {
throw std::runtime_error(FormatError("ir", "BinaryInst 缺少类型信息")); throw std::runtime_error(FormatError("ir", "BinaryInst 缺少类型信息"));
} }
if (lhs_->type()->kind() != rhs_->type()->kind() || if (lhs_->GetType()->GetKind() != rhs_->GetType()->GetKind() ||
type_->kind() != lhs_->type()->kind()) { type_->GetKind() != lhs_->GetType()->GetKind()) {
throw std::runtime_error(FormatError("ir", "BinaryInst 类型不匹配")); throw std::runtime_error(FormatError("ir", "BinaryInst 类型不匹配"));
} }
if (!type_->IsInt32()) { if (!type_->IsInt32()) {
@@ -46,9 +46,9 @@ BinaryInst::BinaryInst(Opcode op, std::shared_ptr<Type> ty, Value* lhs,
} }
} }
Value* BinaryInst::lhs() const { return lhs_; } Value* BinaryInst::GetLhs() const { return lhs_; }
Value* BinaryInst::rhs() const { return rhs_; } Value* BinaryInst::GetRhs() const { return rhs_; }
ReturnInst::ReturnInst(std::shared_ptr<Type> void_ty, Value* val) ReturnInst::ReturnInst(std::shared_ptr<Type> void_ty, Value* val)
: Instruction(Opcode::Ret, std::move(void_ty), ""), : Instruction(Opcode::Ret, std::move(void_ty), ""),
@@ -62,7 +62,7 @@ ReturnInst::ReturnInst(std::shared_ptr<Type> void_ty, Value* val)
value_->AddUser(this); value_->AddUser(this);
} }
Value* ReturnInst::value() const { return value_; } Value* ReturnInst::GetValue() const { return value_; }
AllocaInst::AllocaInst(std::shared_ptr<Type> ptr_ty, std::string name) AllocaInst::AllocaInst(std::shared_ptr<Type> ptr_ty, std::string name)
: Instruction(Opcode::Alloca, std::move(ptr_ty), std::move(name)) { : Instruction(Opcode::Alloca, std::move(ptr_ty), std::move(name)) {
@@ -80,14 +80,14 @@ LoadInst::LoadInst(std::shared_ptr<Type> val_ty, Value* ptr, std::string name)
if (!type_ || !type_->IsInt32()) { if (!type_ || !type_->IsInt32()) {
throw std::runtime_error(FormatError("ir", "LoadInst 当前只支持加载 i32")); throw std::runtime_error(FormatError("ir", "LoadInst 当前只支持加载 i32"));
} }
if (!ptr_->type() || !ptr_->type()->IsPtrInt32()) { if (!ptr_->GetType() || !ptr_->GetType()->IsPtrInt32()) {
throw std::runtime_error( throw std::runtime_error(
FormatError("ir", "LoadInst 当前只支持从 i32* 加载")); FormatError("ir", "LoadInst 当前只支持从 i32* 加载"));
} }
ptr_->AddUser(this); ptr_->AddUser(this);
} }
Value* LoadInst::ptr() const { return ptr_; } Value* LoadInst::GetPtr() const { return ptr_; }
StoreInst::StoreInst(std::shared_ptr<Type> void_ty, Value* val, Value* ptr) StoreInst::StoreInst(std::shared_ptr<Type> void_ty, Value* val, Value* ptr)
: Instruction(Opcode::Store, std::move(void_ty), ""), : Instruction(Opcode::Store, std::move(void_ty), ""),
@@ -102,10 +102,10 @@ StoreInst::StoreInst(std::shared_ptr<Type> void_ty, Value* val, Value* ptr)
if (!type_ || !type_->IsVoid()) { if (!type_ || !type_->IsVoid()) {
throw std::runtime_error(FormatError("ir", "StoreInst 返回类型必须为 void")); throw std::runtime_error(FormatError("ir", "StoreInst 返回类型必须为 void"));
} }
if (!value_->type() || !value_->type()->IsInt32()) { if (!value_->GetType() || !value_->GetType()->IsInt32()) {
throw std::runtime_error(FormatError("ir", "StoreInst 当前只支持存储 i32")); throw std::runtime_error(FormatError("ir", "StoreInst 当前只支持存储 i32"));
} }
if (!ptr_->type() || !ptr_->type()->IsPtrInt32()) { if (!ptr_->GetType() || !ptr_->GetType()->IsPtrInt32()) {
throw std::runtime_error( throw std::runtime_error(
FormatError("ir", "StoreInst 当前只支持写入 i32*")); FormatError("ir", "StoreInst 当前只支持写入 i32*"));
} }
@@ -113,8 +113,8 @@ StoreInst::StoreInst(std::shared_ptr<Type> void_ty, Value* val, Value* ptr)
ptr_->AddUser(this); ptr_->AddUser(this);
} }
Value* StoreInst::value() const { return value_; } Value* StoreInst::GetValue() const { return value_; }
Value* StoreInst::ptr() const { return ptr_; } Value* StoreInst::GetPtr() const { return ptr_; }
} // namespace ir } // namespace ir

View File

@@ -4,9 +4,9 @@
namespace ir { namespace ir {
Context& Module::context() { return context_; } Context& Module::GetContext() { return context_; }
const Context& Module::context() const { return context_; } const Context& Module::GetContext() const { return context_; }
Function* Module::CreateFunction(const std::string& name, Function* Module::CreateFunction(const std::string& name,
std::shared_ptr<Type> ret_type) { std::shared_ptr<Type> ret_type) {
@@ -14,7 +14,7 @@ Function* Module::CreateFunction(const std::string& name,
return functions_.back().get(); return functions_.back().get();
} }
const std::vector<std::unique_ptr<Function>>& Module::functions() const { const std::vector<std::unique_ptr<Function>>& Module::GetFunctions() const {
return functions_; return functions_;
} }

View File

@@ -5,7 +5,7 @@ namespace ir {
Type::Type(Kind k) : kind_(k) {} Type::Type(Kind k) : kind_(k) {}
Type::Kind Type::kind() const { return kind_; } Type::Kind Type::GetKind() const { return kind_; }
bool Type::IsVoid() const { return kind_ == Kind::Void; } bool Type::IsVoid() const { return kind_ == Kind::Void; }

View File

@@ -8,15 +8,15 @@ namespace ir {
Value::Value(std::shared_ptr<Type> ty, std::string name) Value::Value(std::shared_ptr<Type> ty, std::string name)
: type_(std::move(ty)), name_(std::move(name)) {} : type_(std::move(ty)), name_(std::move(name)) {}
const std::shared_ptr<Type>& Value::type() const { return type_; } const std::shared_ptr<Type>& Value::GetType() const { return type_; }
const std::string& Value::name() const { return name_; } const std::string& Value::GetName() const { return name_; }
void Value::set_name(std::string n) { name_ = std::move(n); } void Value::SetName(std::string n) { name_ = std::move(n); }
void Value::AddUser(Instruction* user) { users_.push_back(user); } void Value::AddUser(Instruction* user) { users_.push_back(user); }
const std::vector<Instruction*>& Value::users() const { return users_; } const std::vector<Instruction*>& Value::GetUsers() const { return users_; }
ConstantInt::ConstantInt(std::shared_ptr<Type> ty, int v) ConstantInt::ConstantInt(std::shared_ptr<Type> ty, int v)
: Value(std::move(ty), ""), value_(v) {} : Value(std::move(ty), ""), value_(v) {}

View File

@@ -40,7 +40,7 @@ void IRGenImpl::GenVarDecl(SysYParser::VarDeclContext& decl) {
if (storage_map_.find(&decl) != storage_map_.end()) { if (storage_map_.find(&decl) != storage_map_.end()) {
throw std::runtime_error(FormatError("irgen", "声明重复生成存储槽位")); throw std::runtime_error(FormatError("irgen", "声明重复生成存储槽位"));
} }
auto* slot = builder_.CreateAllocaI32(module_.context().NextTemp()); auto* slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp());
storage_map_[&decl] = slot; storage_map_[&decl] = slot;
ir::Value* init = nullptr; ir::Value* init = nullptr;

View File

@@ -23,7 +23,7 @@ ir::Value* IRGenImpl::GenAddExpr(SysYParser::AddExpContext& add) {
ir::Value* acc = GenPrimary(*terms[0]); ir::Value* acc = GenPrimary(*terms[0]);
for (size_t i = 1; i < terms.size(); ++i) { for (size_t i = 1; i < terms.size(); ++i) {
ir::Value* rhs = GenPrimary(*terms[i]); ir::Value* rhs = GenPrimary(*terms[i]);
std::string name = module_.context().NextTemp(); std::string name = module_.GetContext().NextTemp();
acc = builder_.CreateBinary(ir::Opcode::Add, acc, rhs, name); acc = builder_.CreateBinary(ir::Opcode::Add, acc, rhs, name);
} }
return acc; return acc;
@@ -46,7 +46,7 @@ ir::Value* IRGenImpl::GenPrimary(SysYParser::PrimaryContext& primary) {
FormatError("irgen", FormatError("irgen",
"变量声明缺少存储槽位: " + primary.Ident()->getText())); "变量声明缺少存储槽位: " + primary.Ident()->getText()));
} }
return builder_.CreateLoad(it->second, module_.context().NextTemp()); return builder_.CreateLoad(it->second, module_.GetContext().NextTemp());
} }
if (primary.exp()) { if (primary.exp()) {
return GenExpr(*primary.exp()); return GenExpr(*primary.exp());

View File

@@ -10,11 +10,11 @@ namespace {
void VerifyFunctionStructure(const ir::Function& func) { void VerifyFunctionStructure(const ir::Function& func) {
// 当前 IRGen 仍是单入口、顺序生成;这里在生成结束后补一层块终结校验。 // 当前 IRGen 仍是单入口、顺序生成;这里在生成结束后补一层块终结校验。
for (const auto& bb : func.blocks()) { for (const auto& bb : func.GetBlocks()) {
if (!bb || !bb->HasTerminator()) { if (!bb || !bb->HasTerminator()) {
throw std::runtime_error( throw std::runtime_error(
FormatError("irgen", "基本块未正确终结: " + FormatError("irgen", "基本块未正确终结: " +
(bb ? bb->name() : std::string("<null>")))); (bb ? bb->GetName() : std::string("<null>"))));
} }
} }
} }
@@ -25,7 +25,7 @@ IRGenImpl::IRGenImpl(ir::Module& module, const SemanticContext& sema)
: module_(module), : module_(module),
sema_(sema), sema_(sema),
func_(nullptr), func_(nullptr),
builder_(module.context(), nullptr) {} builder_(module.GetContext(), nullptr) {}
void IRGenImpl::Gen(SysYParser::CompUnitContext& cu) { void IRGenImpl::Gen(SysYParser::CompUnitContext& cu) {
if (!cu.funcDef()) { if (!cu.funcDef()) {
@@ -43,8 +43,8 @@ void IRGenImpl::GenFuncDef(SysYParser::FuncDefContext& func) {
} }
func_ = module_.CreateFunction( func_ = module_.CreateFunction(
func.Ident()->getText(), module_.context().Int32()); func.Ident()->getText(), module_.GetContext().Int32());
builder_.SetInsertPoint(func_->entry()); builder_.SetInsertPoint(func_->GetEntry());
storage_map_.clear(); storage_map_.clear();
GenBlock(*func.block()); GenBlock(*func.block());

View File

@@ -10,10 +10,10 @@ namespace {
const FrameSlot& GetFrameSlot(const MachineFunction& function, const FrameSlot& GetFrameSlot(const MachineFunction& function,
const Operand& operand) { const Operand& operand) {
if (operand.kind() != Operand::Kind::FrameIndex) { if (operand.GetKind() != Operand::Kind::FrameIndex) {
throw std::runtime_error(FormatError("mir", "期望 FrameIndex 操作数")); throw std::runtime_error(FormatError("mir", "期望 FrameIndex 操作数"));
} }
return function.frame_slot(operand.frame_index()); return function.GetFrameSlot(operand.GetFrameIndex());
} }
void PrintStackAccess(std::ostream& os, const char* mnemonic, PhysReg reg, void PrintStackAccess(std::ostream& os, const char* mnemonic, PhysReg reg,
@@ -26,44 +26,44 @@ void PrintStackAccess(std::ostream& os, const char* mnemonic, PhysReg reg,
void PrintAsm(const MachineFunction& function, std::ostream& os) { void PrintAsm(const MachineFunction& function, std::ostream& os) {
os << ".text\n"; os << ".text\n";
os << ".global " << function.name() << "\n"; os << ".global " << function.GetName() << "\n";
os << ".type " << function.name() << ", %function\n"; os << ".type " << function.GetName() << ", %function\n";
os << function.name() << ":\n"; os << function.GetName() << ":\n";
for (const auto& inst : function.entry().instructions()) { for (const auto& inst : function.GetEntry().GetInstructions()) {
const auto& ops = inst.operands(); const auto& ops = inst.GetOperands();
switch (inst.opcode()) { switch (inst.GetOpcode()) {
case Opcode::Prologue: case Opcode::Prologue:
os << " stp x29, x30, [sp, #-16]!\n"; os << " stp x29, x30, [sp, #-16]!\n";
os << " mov x29, sp\n"; os << " mov x29, sp\n";
if (function.frame_size() > 0) { if (function.GetFrameSize() > 0) {
os << " sub sp, sp, #" << function.frame_size() << "\n"; os << " sub sp, sp, #" << function.GetFrameSize() << "\n";
} }
break; break;
case Opcode::Epilogue: case Opcode::Epilogue:
if (function.frame_size() > 0) { if (function.GetFrameSize() > 0) {
os << " add sp, sp, #" << function.frame_size() << "\n"; os << " add sp, sp, #" << function.GetFrameSize() << "\n";
} }
os << " ldp x29, x30, [sp], #16\n"; os << " ldp x29, x30, [sp], #16\n";
break; break;
case Opcode::MovImm: case Opcode::MovImm:
os << " mov " << PhysRegName(ops.at(0).reg()) << ", #" os << " mov " << PhysRegName(ops.at(0).GetReg()) << ", #"
<< ops.at(1).imm() << "\n"; << ops.at(1).GetImm() << "\n";
break; break;
case Opcode::LoadStack: { case Opcode::LoadStack: {
const auto& slot = GetFrameSlot(function, ops.at(1)); const auto& slot = GetFrameSlot(function, ops.at(1));
PrintStackAccess(os, "ldur", ops.at(0).reg(), slot.offset); PrintStackAccess(os, "ldur", ops.at(0).GetReg(), slot.offset);
break; break;
} }
case Opcode::StoreStack: { case Opcode::StoreStack: {
const auto& slot = GetFrameSlot(function, ops.at(1)); const auto& slot = GetFrameSlot(function, ops.at(1));
PrintStackAccess(os, "stur", ops.at(0).reg(), slot.offset); PrintStackAccess(os, "stur", ops.at(0).GetReg(), slot.offset);
break; break;
} }
case Opcode::AddRR: case Opcode::AddRR:
os << " add " << PhysRegName(ops.at(0).reg()) << ", " os << " add " << PhysRegName(ops.at(0).GetReg()) << ", "
<< PhysRegName(ops.at(1).reg()) << ", " << PhysRegName(ops.at(1).GetReg()) << ", "
<< PhysRegName(ops.at(2).reg()) << "\n"; << PhysRegName(ops.at(2).GetReg()) << "\n";
break; break;
case Opcode::Ret: case Opcode::Ret:
os << " ret\n"; os << " ret\n";
@@ -71,7 +71,8 @@ void PrintAsm(const MachineFunction& function, std::ostream& os) {
} }
} }
os << ".size " << function.name() << ", .-" << function.name() << "\n"; os << ".size " << function.GetName() << ", .-" << function.GetName()
<< "\n";
} }
} // namespace mir } // namespace mir

View File

@@ -16,7 +16,7 @@ int AlignTo(int value, int align) {
void RunFrameLowering(MachineFunction& function) { void RunFrameLowering(MachineFunction& function) {
int cursor = 0; int cursor = 0;
for (const auto& slot : function.frame_slots()) { for (const auto& slot : function.GetFrameSlots()) {
cursor += slot.size; cursor += slot.size;
if (-cursor < -256) { if (-cursor < -256) {
throw std::runtime_error(FormatError("mir", "暂不支持过大的栈帧")); throw std::runtime_error(FormatError("mir", "暂不支持过大的栈帧"));
@@ -24,17 +24,17 @@ void RunFrameLowering(MachineFunction& function) {
} }
cursor = 0; cursor = 0;
for (const auto& slot : function.frame_slots()) { for (const auto& slot : function.GetFrameSlots()) {
cursor += slot.size; cursor += slot.size;
function.frame_slot(slot.index).offset = -cursor; function.GetFrameSlot(slot.index).offset = -cursor;
} }
function.set_frame_size(AlignTo(cursor, 16)); function.SetFrameSize(AlignTo(cursor, 16));
auto& insts = function.entry().instructions(); auto& insts = function.GetEntry().GetInstructions();
std::vector<MachineInstr> lowered; std::vector<MachineInstr> lowered;
lowered.emplace_back(Opcode::Prologue); lowered.emplace_back(Opcode::Prologue);
for (const auto& inst : insts) { for (const auto& inst : insts) {
if (inst.opcode() == Opcode::Ret) { if (inst.GetOpcode() == Opcode::Ret) {
lowered.emplace_back(Opcode::Epilogue); lowered.emplace_back(Opcode::Epilogue);
} }
lowered.push_back(inst); lowered.push_back(inst);

View File

@@ -15,14 +15,14 @@ void EmitValueToReg(const ir::Value* value, PhysReg target,
const ValueSlotMap& slots, MachineBasicBlock& block) { const ValueSlotMap& slots, MachineBasicBlock& block) {
if (auto* constant = dynamic_cast<const ir::ConstantInt*>(value)) { if (auto* constant = dynamic_cast<const ir::ConstantInt*>(value)) {
block.Append(Opcode::MovImm, block.Append(Opcode::MovImm,
{Operand::Reg(target), Operand::Imm(constant->value())}); {Operand::Reg(target), Operand::Imm(constant->GetValue())});
return; return;
} }
auto it = slots.find(value); auto it = slots.find(value);
if (it == slots.end()) { if (it == slots.end()) {
throw std::runtime_error( throw std::runtime_error(
FormatError("mir", "找不到值对应的栈槽: " + value->name())); FormatError("mir", "找不到值对应的栈槽: " + value->GetName()));
} }
block.Append(Opcode::LoadStack, block.Append(Opcode::LoadStack,
@@ -31,28 +31,28 @@ void EmitValueToReg(const ir::Value* value, PhysReg target,
void LowerInstruction(const ir::Instruction& inst, MachineFunction& function, void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
ValueSlotMap& slots) { ValueSlotMap& slots) {
auto& block = function.entry(); auto& block = function.GetEntry();
switch (inst.opcode()) { switch (inst.GetOpcode()) {
case ir::Opcode::Alloca: { case ir::Opcode::Alloca: {
slots.emplace(&inst, function.CreateFrameIndex()); slots.emplace(&inst, function.CreateFrameIndex());
return; return;
} }
case ir::Opcode::Store: { case ir::Opcode::Store: {
auto& store = static_cast<const ir::StoreInst&>(inst); auto& store = static_cast<const ir::StoreInst&>(inst);
auto dst = slots.find(store.ptr()); auto dst = slots.find(store.GetPtr());
if (dst == slots.end()) { if (dst == slots.end()) {
throw std::runtime_error( throw std::runtime_error(
FormatError("mir", "暂不支持对非栈变量地址进行写入")); FormatError("mir", "暂不支持对非栈变量地址进行写入"));
} }
EmitValueToReg(store.value(), PhysReg::W8, slots, block); EmitValueToReg(store.GetValue(), PhysReg::W8, slots, block);
block.Append(Opcode::StoreStack, block.Append(Opcode::StoreStack,
{Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst->second)}); {Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst->second)});
return; return;
} }
case ir::Opcode::Load: { case ir::Opcode::Load: {
auto& load = static_cast<const ir::LoadInst&>(inst); auto& load = static_cast<const ir::LoadInst&>(inst);
auto src = slots.find(load.ptr()); auto src = slots.find(load.GetPtr());
if (src == slots.end()) { if (src == slots.end()) {
throw std::runtime_error( throw std::runtime_error(
FormatError("mir", "暂不支持对非栈变量地址进行读取")); FormatError("mir", "暂不支持对非栈变量地址进行读取"));
@@ -68,8 +68,8 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
case ir::Opcode::Add: { case ir::Opcode::Add: {
auto& bin = static_cast<const ir::BinaryInst&>(inst); auto& bin = static_cast<const ir::BinaryInst&>(inst);
int dst_slot = function.CreateFrameIndex(); int dst_slot = function.CreateFrameIndex();
EmitValueToReg(bin.lhs(), PhysReg::W8, slots, block); EmitValueToReg(bin.GetLhs(), PhysReg::W8, slots, block);
EmitValueToReg(bin.rhs(), PhysReg::W9, slots, block); EmitValueToReg(bin.GetRhs(), PhysReg::W9, slots, block);
block.Append(Opcode::AddRR, {Operand::Reg(PhysReg::W8), block.Append(Opcode::AddRR, {Operand::Reg(PhysReg::W8),
Operand::Reg(PhysReg::W8), Operand::Reg(PhysReg::W8),
Operand::Reg(PhysReg::W9)}); Operand::Reg(PhysReg::W9)});
@@ -80,7 +80,7 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
} }
case ir::Opcode::Ret: { case ir::Opcode::Ret: {
auto& ret = static_cast<const ir::ReturnInst&>(inst); auto& ret = static_cast<const ir::ReturnInst&>(inst);
EmitValueToReg(ret.value(), PhysReg::W0, slots, block); EmitValueToReg(ret.GetValue(), PhysReg::W0, slots, block);
block.Append(Opcode::Ret); block.Append(Opcode::Ret);
return; return;
} }
@@ -97,23 +97,23 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
std::unique_ptr<MachineFunction> LowerToMIR(const ir::Module& module) { std::unique_ptr<MachineFunction> LowerToMIR(const ir::Module& module) {
DefaultContext(); DefaultContext();
if (module.functions().size() != 1) { if (module.GetFunctions().size() != 1) {
throw std::runtime_error(FormatError("mir", "暂不支持多个函数")); throw std::runtime_error(FormatError("mir", "暂不支持多个函数"));
} }
const auto& func = *module.functions().front(); const auto& func = *module.GetFunctions().front();
if (func.name() != "main") { if (func.GetName() != "main") {
throw std::runtime_error(FormatError("mir", "暂不支持非 main 函数")); throw std::runtime_error(FormatError("mir", "暂不支持非 main 函数"));
} }
auto machine_func = std::make_unique<MachineFunction>(func.name()); auto machine_func = std::make_unique<MachineFunction>(func.GetName());
ValueSlotMap slots; ValueSlotMap slots;
const auto* entry = func.entry(); const auto* entry = func.GetEntry();
if (!entry) { if (!entry) {
throw std::runtime_error(FormatError("mir", "IR 函数缺少入口基本块")); throw std::runtime_error(FormatError("mir", "IR 函数缺少入口基本块"));
} }
for (const auto& inst : entry->instructions()) { for (const auto& inst : entry->GetInstructions()) {
LowerInstruction(*inst, *machine_func, slots); LowerInstruction(*inst, *machine_func, slots);
} }

View File

@@ -16,14 +16,14 @@ int MachineFunction::CreateFrameIndex(int size) {
return index; return index;
} }
FrameSlot& MachineFunction::frame_slot(int index) { FrameSlot& MachineFunction::GetFrameSlot(int index) {
if (index < 0 || index >= static_cast<int>(frame_slots_.size())) { if (index < 0 || index >= static_cast<int>(frame_slots_.size())) {
throw std::runtime_error(FormatError("mir", "非法 FrameIndex")); throw std::runtime_error(FormatError("mir", "非法 FrameIndex"));
} }
return frame_slots_[index]; return frame_slots_[index];
} }
const FrameSlot& MachineFunction::frame_slot(int index) const { const FrameSlot& MachineFunction::GetFrameSlot(int index) const {
if (index < 0 || index >= static_cast<int>(frame_slots_.size())) { if (index < 0 || index >= static_cast<int>(frame_slots_.size())) {
throw std::runtime_error(FormatError("mir", "非法 FrameIndex")); throw std::runtime_error(FormatError("mir", "非法 FrameIndex"));
} }

View File

@@ -23,9 +23,10 @@ bool IsAllowedReg(PhysReg reg) {
} // namespace } // namespace
void RunRegAlloc(MachineFunction& function) { void RunRegAlloc(MachineFunction& function) {
for (const auto& inst : function.entry().instructions()) { for (const auto& inst : function.GetEntry().GetInstructions()) {
for (const auto& operand : inst.operands()) { for (const auto& operand : inst.GetOperands()) {
if (operand.kind() == Operand::Kind::Reg && !IsAllowedReg(operand.reg())) { if (operand.GetKind() == Operand::Kind::Reg &&
!IsAllowedReg(operand.GetReg())) {
throw std::runtime_error(FormatError("mir", "寄存器分配失败")); throw std::runtime_error(FormatError("mir", "寄存器分配失败"));
} }
} }