refactor(dev): 统一 IR/MIR 接口命名风格
This commit is contained in:
@@ -43,7 +43,7 @@ class Type {
|
||||
public:
|
||||
enum class Kind { Void, Int32, PtrInt32 };
|
||||
explicit Type(Kind k);
|
||||
Kind kind() const;
|
||||
Kind GetKind() const;
|
||||
bool IsVoid() const;
|
||||
bool IsInt32() const;
|
||||
bool IsPtrInt32() const;
|
||||
@@ -56,11 +56,11 @@ class Value {
|
||||
public:
|
||||
Value(std::shared_ptr<Type> ty, std::string name);
|
||||
virtual ~Value() = default;
|
||||
const std::shared_ptr<Type>& type() const;
|
||||
const std::string& name() const;
|
||||
void set_name(std::string n);
|
||||
const std::shared_ptr<Type>& GetType() const;
|
||||
const std::string& GetName() const;
|
||||
void SetName(std::string n);
|
||||
void AddUser(Instruction* user);
|
||||
const std::vector<Instruction*>& users() const;
|
||||
const std::vector<Instruction*>& GetUsers() const;
|
||||
|
||||
protected:
|
||||
std::shared_ptr<Type> type_;
|
||||
@@ -71,7 +71,7 @@ class Value {
|
||||
class ConstantInt : public Value {
|
||||
public:
|
||||
ConstantInt(std::shared_ptr<Type> ty, int v);
|
||||
int value() const { return value_; }
|
||||
int GetValue() const { return value_; }
|
||||
|
||||
private:
|
||||
int value_{};
|
||||
@@ -83,10 +83,10 @@ enum class Opcode { Add, Sub, Mul, Alloca, Load, Store, Ret };
|
||||
class Instruction : public Value {
|
||||
public:
|
||||
Instruction(Opcode op, std::shared_ptr<Type> ty, std::string name = "");
|
||||
Opcode opcode() const;
|
||||
Opcode GetOpcode() const;
|
||||
bool IsTerminator() const;
|
||||
BasicBlock* parent() const;
|
||||
void set_parent(BasicBlock* parent);
|
||||
BasicBlock* GetParent() const;
|
||||
void SetParent(BasicBlock* parent);
|
||||
|
||||
private:
|
||||
Opcode opcode_;
|
||||
@@ -97,8 +97,8 @@ class BinaryInst : public Instruction {
|
||||
public:
|
||||
BinaryInst(Opcode op, std::shared_ptr<Type> ty, Value* lhs, Value* rhs,
|
||||
std::string name);
|
||||
Value* lhs() const;
|
||||
Value* rhs() const;
|
||||
Value* GetLhs() const;
|
||||
Value* GetRhs() const;
|
||||
|
||||
private:
|
||||
Value* lhs_;
|
||||
@@ -108,7 +108,7 @@ class BinaryInst : public Instruction {
|
||||
class ReturnInst : public Instruction {
|
||||
public:
|
||||
ReturnInst(std::shared_ptr<Type> void_ty, Value* val);
|
||||
Value* value() const;
|
||||
Value* GetValue() const;
|
||||
|
||||
private:
|
||||
Value* value_;
|
||||
@@ -122,7 +122,7 @@ class AllocaInst : public Instruction {
|
||||
class LoadInst : public Instruction {
|
||||
public:
|
||||
LoadInst(std::shared_ptr<Type> val_ty, Value* ptr, std::string name);
|
||||
Value* ptr() const;
|
||||
Value* GetPtr() const;
|
||||
|
||||
private:
|
||||
Value* ptr_;
|
||||
@@ -131,8 +131,8 @@ class LoadInst : public Instruction {
|
||||
class StoreInst : public Instruction {
|
||||
public:
|
||||
StoreInst(std::shared_ptr<Type> void_ty, Value* val, Value* ptr);
|
||||
Value* value() const;
|
||||
Value* ptr() const;
|
||||
Value* GetValue() const;
|
||||
Value* GetPtr() const;
|
||||
|
||||
private:
|
||||
Value* value_;
|
||||
@@ -142,13 +142,13 @@ class StoreInst : public Instruction {
|
||||
class BasicBlock {
|
||||
public:
|
||||
explicit BasicBlock(std::string name);
|
||||
const std::string& name() const;
|
||||
Function* parent() const;
|
||||
void set_parent(Function* parent);
|
||||
const std::string& GetName() const;
|
||||
Function* GetParent() const;
|
||||
void SetParent(Function* parent);
|
||||
bool HasTerminator() const;
|
||||
const std::vector<std::unique_ptr<Instruction>>& instructions() const;
|
||||
const std::vector<BasicBlock*>& predecessors() const;
|
||||
const std::vector<BasicBlock*>& successors() const;
|
||||
const std::vector<std::unique_ptr<Instruction>>& GetInstructions() const;
|
||||
const std::vector<BasicBlock*>& GetPredecessors() const;
|
||||
const std::vector<BasicBlock*>& GetSuccessors() const;
|
||||
template <typename T, typename... Args>
|
||||
T* Append(Args&&... args) {
|
||||
if (HasTerminator()) {
|
||||
@@ -157,7 +157,7 @@ class BasicBlock {
|
||||
}
|
||||
auto inst = std::make_unique<T>(std::forward<Args>(args)...);
|
||||
auto* ptr = inst.get();
|
||||
ptr->set_parent(this);
|
||||
ptr->SetParent(this);
|
||||
instructions_.push_back(std::move(inst));
|
||||
return ptr;
|
||||
}
|
||||
@@ -175,9 +175,9 @@ class Function : public Value {
|
||||
// 允许显式指定返回类型,便于后续扩展多种函数签名。
|
||||
Function(std::string name, std::shared_ptr<Type> ret_type);
|
||||
BasicBlock* CreateBlock(const std::string& name);
|
||||
BasicBlock* entry();
|
||||
const BasicBlock* entry() const;
|
||||
const std::vector<std::unique_ptr<BasicBlock>>& blocks() const;
|
||||
BasicBlock* GetEntry();
|
||||
const BasicBlock* GetEntry() const;
|
||||
const std::vector<std::unique_ptr<BasicBlock>>& GetBlocks() const;
|
||||
|
||||
private:
|
||||
BasicBlock* entry_ = nullptr;
|
||||
@@ -187,12 +187,12 @@ class Function : public Value {
|
||||
class Module {
|
||||
public:
|
||||
Module() = default;
|
||||
Context& context();
|
||||
const Context& context() const;
|
||||
Context& GetContext();
|
||||
const Context& GetContext() const;
|
||||
// 创建函数时显式传入返回类型,便于在 IRGen 中根据语法树信息选择类型。
|
||||
Function* CreateFunction(const std::string& name,
|
||||
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:
|
||||
Context context_;
|
||||
@@ -217,7 +217,7 @@ class IRBuilder {
|
||||
|
||||
private:
|
||||
Context& ctx_;
|
||||
BasicBlock* insertBlock_;
|
||||
BasicBlock* insert_block_;
|
||||
};
|
||||
|
||||
class IRPrinter {
|
||||
|
||||
@@ -41,10 +41,10 @@ class Operand {
|
||||
static Operand Imm(int value);
|
||||
static Operand FrameIndex(int index);
|
||||
|
||||
Kind kind() const { return kind_; }
|
||||
PhysReg reg() const { return reg_; }
|
||||
int imm() const { return imm_; }
|
||||
int frame_index() const { return imm_; }
|
||||
Kind GetKind() const { return kind_; }
|
||||
PhysReg GetReg() const { return reg_; }
|
||||
int GetImm() const { return imm_; }
|
||||
int GetFrameIndex() const { return imm_; }
|
||||
|
||||
private:
|
||||
Operand(Kind kind, PhysReg reg, int imm);
|
||||
@@ -58,8 +58,8 @@ class MachineInstr {
|
||||
public:
|
||||
MachineInstr(Opcode opcode, std::vector<Operand> operands = {});
|
||||
|
||||
Opcode opcode() const { return opcode_; }
|
||||
const std::vector<Operand>& operands() const { return operands_; }
|
||||
Opcode GetOpcode() const { return opcode_; }
|
||||
const std::vector<Operand>& GetOperands() const { return operands_; }
|
||||
|
||||
private:
|
||||
Opcode opcode_;
|
||||
@@ -76,9 +76,9 @@ class MachineBasicBlock {
|
||||
public:
|
||||
explicit MachineBasicBlock(std::string name);
|
||||
|
||||
const std::string& name() const { return name_; }
|
||||
std::vector<MachineInstr>& instructions() { return instructions_; }
|
||||
const std::vector<MachineInstr>& instructions() const { return instructions_; }
|
||||
const std::string& GetName() const { return name_; }
|
||||
std::vector<MachineInstr>& GetInstructions() { return instructions_; }
|
||||
const std::vector<MachineInstr>& GetInstructions() const { return instructions_; }
|
||||
|
||||
MachineInstr& Append(Opcode opcode,
|
||||
std::initializer_list<Operand> operands = {});
|
||||
@@ -92,17 +92,17 @@ class MachineFunction {
|
||||
public:
|
||||
explicit MachineFunction(std::string name);
|
||||
|
||||
const std::string& name() const { return name_; }
|
||||
MachineBasicBlock& entry() { return entry_; }
|
||||
const MachineBasicBlock& entry() const { return entry_; }
|
||||
const std::string& GetName() const { return name_; }
|
||||
MachineBasicBlock& GetEntry() { return entry_; }
|
||||
const MachineBasicBlock& GetEntry() const { return entry_; }
|
||||
|
||||
int CreateFrameIndex(int size = 4);
|
||||
FrameSlot& frame_slot(int index);
|
||||
const FrameSlot& frame_slot(int index) const;
|
||||
const std::vector<FrameSlot>& frame_slots() const { return frame_slots_; }
|
||||
FrameSlot& GetFrameSlot(int index);
|
||||
const FrameSlot& GetFrameSlot(int index) const;
|
||||
const std::vector<FrameSlot>& GetFrameSlots() const { return frame_slots_; }
|
||||
|
||||
int frame_size() const { return frame_size_; }
|
||||
void set_frame_size(int size) { frame_size_ = size; }
|
||||
int GetFrameSize() const { return frame_size_; }
|
||||
void SetFrameSize(int size) { frame_size_ = size; }
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
|
||||
@@ -10,26 +10,26 @@ namespace ir {
|
||||
|
||||
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 {
|
||||
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 {
|
||||
return instructions_;
|
||||
}
|
||||
|
||||
const std::vector<BasicBlock*>& BasicBlock::predecessors() const {
|
||||
const std::vector<BasicBlock*>& BasicBlock::GetPredecessors() const {
|
||||
return predecessors_;
|
||||
}
|
||||
|
||||
const std::vector<BasicBlock*>& BasicBlock::successors() const {
|
||||
const std::vector<BasicBlock*>& BasicBlock::GetSuccessors() const {
|
||||
return successors_;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ Function::Function(std::string name, std::shared_ptr<Type> ret_type)
|
||||
BasicBlock* Function::CreateBlock(const std::string& name) {
|
||||
auto block = std::make_unique<BasicBlock>(name);
|
||||
auto* ptr = block.get();
|
||||
ptr->set_parent(this);
|
||||
ptr->SetParent(this);
|
||||
blocks_.push_back(std::move(block));
|
||||
if (!entry_) {
|
||||
entry_ = ptr;
|
||||
@@ -21,11 +21,11 @@ BasicBlock* Function::CreateBlock(const std::string& name) {
|
||||
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_;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
|
||||
namespace ir {
|
||||
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) {
|
||||
// 常量不需要挂在基本块里,由 Context 负责去重与生命周期。
|
||||
@@ -23,7 +23,7 @@ ConstantInt* IRBuilder::CreateConstInt(int v) {
|
||||
|
||||
BinaryInst* IRBuilder::CreateBinary(Opcode op, Value* lhs, Value* rhs,
|
||||
const std::string& name) {
|
||||
if (!insertBlock_) {
|
||||
if (!insert_block_) {
|
||||
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
|
||||
}
|
||||
if (!lhs) {
|
||||
@@ -34,7 +34,7 @@ BinaryInst* IRBuilder::CreateBinary(Opcode op, Value* lhs, Value* rhs,
|
||||
throw std::runtime_error(
|
||||
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,
|
||||
@@ -43,25 +43,25 @@ BinaryInst* IRBuilder::CreateAdd(Value* lhs, Value* rhs,
|
||||
}
|
||||
|
||||
AllocaInst* IRBuilder::CreateAllocaI32(const std::string& name) {
|
||||
if (!insertBlock_) {
|
||||
if (!insert_block_) {
|
||||
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) {
|
||||
if (!insertBlock_) {
|
||||
if (!insert_block_) {
|
||||
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
|
||||
}
|
||||
if (!ptr) {
|
||||
throw std::runtime_error(
|
||||
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) {
|
||||
if (!insertBlock_) {
|
||||
if (!insert_block_) {
|
||||
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
|
||||
}
|
||||
if (!val) {
|
||||
@@ -72,18 +72,18 @@ StoreInst* IRBuilder::CreateStore(Value* val, Value* ptr) {
|
||||
throw std::runtime_error(
|
||||
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) {
|
||||
if (!insertBlock_) {
|
||||
if (!insert_block_) {
|
||||
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
|
||||
}
|
||||
if (!v) {
|
||||
throw std::runtime_error(
|
||||
FormatError("ir", "IRBuilder::CreateRet 缺少返回值"));
|
||||
}
|
||||
return insertBlock_->Append<ReturnInst>(ctx_.Void(), v);
|
||||
return insert_block_->Append<ReturnInst>(ctx_.Void(), v);
|
||||
}
|
||||
|
||||
} // namespace ir
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
namespace ir {
|
||||
|
||||
static const char* TypeToString(const Type& ty) {
|
||||
switch (ty.kind()) {
|
||||
switch (ty.GetKind()) {
|
||||
case Type::Kind::Void:
|
||||
return "void";
|
||||
case Type::Kind::Int32:
|
||||
@@ -46,54 +46,55 @@ static const char* OpcodeToString(Opcode op) {
|
||||
|
||||
static std::string ValueToString(const Value* 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) {
|
||||
for (const auto& func : module.functions()) {
|
||||
os << "define " << TypeToString(*func->type()) << " @" << func->name()
|
||||
for (const auto& func : module.GetFunctions()) {
|
||||
os << "define " << TypeToString(*func->GetType()) << " @" << func->GetName()
|
||||
<< "() {\n";
|
||||
for (const auto& bb : func->blocks()) {
|
||||
for (const auto& bb : func->GetBlocks()) {
|
||||
if (!bb) {
|
||||
continue;
|
||||
}
|
||||
os << bb->name() << ":\n";
|
||||
for (const auto& instPtr : bb->instructions()) {
|
||||
os << bb->GetName() << ":\n";
|
||||
for (const auto& instPtr : bb->GetInstructions()) {
|
||||
const auto* inst = instPtr.get();
|
||||
switch (inst->opcode()) {
|
||||
switch (inst->GetOpcode()) {
|
||||
case Opcode::Add:
|
||||
case Opcode::Sub:
|
||||
case Opcode::Mul: {
|
||||
auto* bin = static_cast<const BinaryInst*>(inst);
|
||||
os << " " << bin->name() << " = " << OpcodeToString(bin->opcode())
|
||||
<< " " << TypeToString(*bin->lhs()->type()) << " "
|
||||
<< ValueToString(bin->lhs()) << ", "
|
||||
<< ValueToString(bin->rhs()) << "\n";
|
||||
os << " " << bin->GetName() << " = "
|
||||
<< OpcodeToString(bin->GetOpcode()) << " "
|
||||
<< TypeToString(*bin->GetLhs()->GetType()) << " "
|
||||
<< ValueToString(bin->GetLhs()) << ", "
|
||||
<< ValueToString(bin->GetRhs()) << "\n";
|
||||
break;
|
||||
}
|
||||
case Opcode::Alloca: {
|
||||
auto* alloca = static_cast<const AllocaInst*>(inst);
|
||||
os << " " << alloca->name() << " = alloca i32\n";
|
||||
os << " " << alloca->GetName() << " = alloca i32\n";
|
||||
break;
|
||||
}
|
||||
case Opcode::Load: {
|
||||
auto* load = static_cast<const LoadInst*>(inst);
|
||||
os << " " << load->name() << " = load i32, i32* "
|
||||
<< ValueToString(load->ptr()) << "\n";
|
||||
os << " " << load->GetName() << " = load i32, i32* "
|
||||
<< ValueToString(load->GetPtr()) << "\n";
|
||||
break;
|
||||
}
|
||||
case Opcode::Store: {
|
||||
auto* store = static_cast<const StoreInst*>(inst);
|
||||
os << " store i32 " << ValueToString(store->value()) << ", i32* "
|
||||
<< ValueToString(store->ptr()) << "\n";
|
||||
os << " store i32 " << ValueToString(store->GetValue())
|
||||
<< ", i32* " << ValueToString(store->GetPtr()) << "\n";
|
||||
break;
|
||||
}
|
||||
case Opcode::Ret: {
|
||||
auto* ret = static_cast<const ReturnInst*>(inst);
|
||||
os << " ret " << TypeToString(*ret->value()->type()) << " "
|
||||
<< ValueToString(ret->value()) << "\n";
|
||||
os << " ret " << TypeToString(*ret->GetValue()->GetType()) << " "
|
||||
<< ValueToString(ret->GetValue()) << "\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,13 +11,13 @@ namespace ir {
|
||||
Instruction::Instruction(Opcode op, std::shared_ptr<Type> ty, std::string name)
|
||||
: 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; }
|
||||
|
||||
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,
|
||||
Value* rhs, std::string name)
|
||||
@@ -28,11 +28,11 @@ BinaryInst::BinaryInst(Opcode op, std::shared_ptr<Type> ty, Value* lhs,
|
||||
if (!lhs_ || !rhs_) {
|
||||
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 缺少类型信息"));
|
||||
}
|
||||
if (lhs_->type()->kind() != rhs_->type()->kind() ||
|
||||
type_->kind() != lhs_->type()->kind()) {
|
||||
if (lhs_->GetType()->GetKind() != rhs_->GetType()->GetKind() ||
|
||||
type_->GetKind() != lhs_->GetType()->GetKind()) {
|
||||
throw std::runtime_error(FormatError("ir", "BinaryInst 类型不匹配"));
|
||||
}
|
||||
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)
|
||||
: 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* ReturnInst::value() const { return value_; }
|
||||
Value* ReturnInst::GetValue() const { return value_; }
|
||||
|
||||
AllocaInst::AllocaInst(std::shared_ptr<Type> ptr_ty, std::string 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()) {
|
||||
throw std::runtime_error(FormatError("ir", "LoadInst 当前只支持加载 i32"));
|
||||
}
|
||||
if (!ptr_->type() || !ptr_->type()->IsPtrInt32()) {
|
||||
if (!ptr_->GetType() || !ptr_->GetType()->IsPtrInt32()) {
|
||||
throw std::runtime_error(
|
||||
FormatError("ir", "LoadInst 当前只支持从 i32* 加载"));
|
||||
}
|
||||
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)
|
||||
: 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()) {
|
||||
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"));
|
||||
}
|
||||
if (!ptr_->type() || !ptr_->type()->IsPtrInt32()) {
|
||||
if (!ptr_->GetType() || !ptr_->GetType()->IsPtrInt32()) {
|
||||
throw std::runtime_error(
|
||||
FormatError("ir", "StoreInst 当前只支持写入 i32*"));
|
||||
}
|
||||
@@ -113,8 +113,8 @@ StoreInst::StoreInst(std::shared_ptr<Type> void_ty, Value* val, Value* ptr)
|
||||
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
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
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,
|
||||
std::shared_ptr<Type> ret_type) {
|
||||
@@ -14,7 +14,7 @@ Function* Module::CreateFunction(const std::string& name,
|
||||
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_;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace ir {
|
||||
|
||||
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; }
|
||||
|
||||
|
||||
@@ -8,15 +8,15 @@ namespace ir {
|
||||
Value::Value(std::shared_ptr<Type> ty, std::string 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); }
|
||||
|
||||
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)
|
||||
: Value(std::move(ty), ""), value_(v) {}
|
||||
|
||||
@@ -40,7 +40,7 @@ void IRGenImpl::GenVarDecl(SysYParser::VarDeclContext& decl) {
|
||||
if (storage_map_.find(&decl) != storage_map_.end()) {
|
||||
throw std::runtime_error(FormatError("irgen", "声明重复生成存储槽位"));
|
||||
}
|
||||
auto* slot = builder_.CreateAllocaI32(module_.context().NextTemp());
|
||||
auto* slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp());
|
||||
storage_map_[&decl] = slot;
|
||||
|
||||
ir::Value* init = nullptr;
|
||||
|
||||
@@ -23,7 +23,7 @@ ir::Value* IRGenImpl::GenAddExpr(SysYParser::AddExpContext& add) {
|
||||
ir::Value* acc = GenPrimary(*terms[0]);
|
||||
for (size_t i = 1; i < terms.size(); ++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);
|
||||
}
|
||||
return acc;
|
||||
@@ -46,7 +46,7 @@ ir::Value* IRGenImpl::GenPrimary(SysYParser::PrimaryContext& primary) {
|
||||
FormatError("irgen",
|
||||
"变量声明缺少存储槽位: " + primary.Ident()->getText()));
|
||||
}
|
||||
return builder_.CreateLoad(it->second, module_.context().NextTemp());
|
||||
return builder_.CreateLoad(it->second, module_.GetContext().NextTemp());
|
||||
}
|
||||
if (primary.exp()) {
|
||||
return GenExpr(*primary.exp());
|
||||
|
||||
@@ -10,11 +10,11 @@ namespace {
|
||||
|
||||
void VerifyFunctionStructure(const ir::Function& func) {
|
||||
// 当前 IRGen 仍是单入口、顺序生成;这里在生成结束后补一层块终结校验。
|
||||
for (const auto& bb : func.blocks()) {
|
||||
for (const auto& bb : func.GetBlocks()) {
|
||||
if (!bb || !bb->HasTerminator()) {
|
||||
throw std::runtime_error(
|
||||
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),
|
||||
sema_(sema),
|
||||
func_(nullptr),
|
||||
builder_(module.context(), nullptr) {}
|
||||
builder_(module.GetContext(), nullptr) {}
|
||||
|
||||
void IRGenImpl::Gen(SysYParser::CompUnitContext& cu) {
|
||||
if (!cu.funcDef()) {
|
||||
@@ -43,8 +43,8 @@ void IRGenImpl::GenFuncDef(SysYParser::FuncDefContext& func) {
|
||||
}
|
||||
|
||||
func_ = module_.CreateFunction(
|
||||
func.Ident()->getText(), module_.context().Int32());
|
||||
builder_.SetInsertPoint(func_->entry());
|
||||
func.Ident()->getText(), module_.GetContext().Int32());
|
||||
builder_.SetInsertPoint(func_->GetEntry());
|
||||
storage_map_.clear();
|
||||
|
||||
GenBlock(*func.block());
|
||||
|
||||
@@ -10,10 +10,10 @@ namespace {
|
||||
|
||||
const FrameSlot& GetFrameSlot(const MachineFunction& function,
|
||||
const Operand& operand) {
|
||||
if (operand.kind() != Operand::Kind::FrameIndex) {
|
||||
if (operand.GetKind() != Operand::Kind::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,
|
||||
@@ -26,44 +26,44 @@ void PrintStackAccess(std::ostream& os, const char* mnemonic, PhysReg reg,
|
||||
|
||||
void PrintAsm(const MachineFunction& function, std::ostream& os) {
|
||||
os << ".text\n";
|
||||
os << ".global " << function.name() << "\n";
|
||||
os << ".type " << function.name() << ", %function\n";
|
||||
os << function.name() << ":\n";
|
||||
os << ".global " << function.GetName() << "\n";
|
||||
os << ".type " << function.GetName() << ", %function\n";
|
||||
os << function.GetName() << ":\n";
|
||||
|
||||
for (const auto& inst : function.entry().instructions()) {
|
||||
const auto& ops = inst.operands();
|
||||
switch (inst.opcode()) {
|
||||
for (const auto& inst : function.GetEntry().GetInstructions()) {
|
||||
const auto& ops = inst.GetOperands();
|
||||
switch (inst.GetOpcode()) {
|
||||
case Opcode::Prologue:
|
||||
os << " stp x29, x30, [sp, #-16]!\n";
|
||||
os << " mov x29, sp\n";
|
||||
if (function.frame_size() > 0) {
|
||||
os << " sub sp, sp, #" << function.frame_size() << "\n";
|
||||
if (function.GetFrameSize() > 0) {
|
||||
os << " sub sp, sp, #" << function.GetFrameSize() << "\n";
|
||||
}
|
||||
break;
|
||||
case Opcode::Epilogue:
|
||||
if (function.frame_size() > 0) {
|
||||
os << " add sp, sp, #" << function.frame_size() << "\n";
|
||||
if (function.GetFrameSize() > 0) {
|
||||
os << " add sp, sp, #" << function.GetFrameSize() << "\n";
|
||||
}
|
||||
os << " ldp x29, x30, [sp], #16\n";
|
||||
break;
|
||||
case Opcode::MovImm:
|
||||
os << " mov " << PhysRegName(ops.at(0).reg()) << ", #"
|
||||
<< ops.at(1).imm() << "\n";
|
||||
os << " mov " << PhysRegName(ops.at(0).GetReg()) << ", #"
|
||||
<< ops.at(1).GetImm() << "\n";
|
||||
break;
|
||||
case Opcode::LoadStack: {
|
||||
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;
|
||||
}
|
||||
case Opcode::StoreStack: {
|
||||
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;
|
||||
}
|
||||
case Opcode::AddRR:
|
||||
os << " add " << PhysRegName(ops.at(0).reg()) << ", "
|
||||
<< PhysRegName(ops.at(1).reg()) << ", "
|
||||
<< PhysRegName(ops.at(2).reg()) << "\n";
|
||||
os << " add " << PhysRegName(ops.at(0).GetReg()) << ", "
|
||||
<< PhysRegName(ops.at(1).GetReg()) << ", "
|
||||
<< PhysRegName(ops.at(2).GetReg()) << "\n";
|
||||
break;
|
||||
case Opcode::Ret:
|
||||
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
|
||||
|
||||
@@ -16,7 +16,7 @@ int AlignTo(int value, int align) {
|
||||
|
||||
void RunFrameLowering(MachineFunction& function) {
|
||||
int cursor = 0;
|
||||
for (const auto& slot : function.frame_slots()) {
|
||||
for (const auto& slot : function.GetFrameSlots()) {
|
||||
cursor += slot.size;
|
||||
if (-cursor < -256) {
|
||||
throw std::runtime_error(FormatError("mir", "暂不支持过大的栈帧"));
|
||||
@@ -24,17 +24,17 @@ void RunFrameLowering(MachineFunction& function) {
|
||||
}
|
||||
|
||||
cursor = 0;
|
||||
for (const auto& slot : function.frame_slots()) {
|
||||
for (const auto& slot : function.GetFrameSlots()) {
|
||||
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;
|
||||
lowered.emplace_back(Opcode::Prologue);
|
||||
for (const auto& inst : insts) {
|
||||
if (inst.opcode() == Opcode::Ret) {
|
||||
if (inst.GetOpcode() == Opcode::Ret) {
|
||||
lowered.emplace_back(Opcode::Epilogue);
|
||||
}
|
||||
lowered.push_back(inst);
|
||||
|
||||
@@ -15,14 +15,14 @@ void EmitValueToReg(const ir::Value* value, PhysReg target,
|
||||
const ValueSlotMap& slots, MachineBasicBlock& block) {
|
||||
if (auto* constant = dynamic_cast<const ir::ConstantInt*>(value)) {
|
||||
block.Append(Opcode::MovImm,
|
||||
{Operand::Reg(target), Operand::Imm(constant->value())});
|
||||
{Operand::Reg(target), Operand::Imm(constant->GetValue())});
|
||||
return;
|
||||
}
|
||||
|
||||
auto it = slots.find(value);
|
||||
if (it == slots.end()) {
|
||||
throw std::runtime_error(
|
||||
FormatError("mir", "找不到值对应的栈槽: " + value->name()));
|
||||
FormatError("mir", "找不到值对应的栈槽: " + value->GetName()));
|
||||
}
|
||||
|
||||
block.Append(Opcode::LoadStack,
|
||||
@@ -31,28 +31,28 @@ void EmitValueToReg(const ir::Value* value, PhysReg target,
|
||||
|
||||
void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
||||
ValueSlotMap& slots) {
|
||||
auto& block = function.entry();
|
||||
auto& block = function.GetEntry();
|
||||
|
||||
switch (inst.opcode()) {
|
||||
switch (inst.GetOpcode()) {
|
||||
case ir::Opcode::Alloca: {
|
||||
slots.emplace(&inst, function.CreateFrameIndex());
|
||||
return;
|
||||
}
|
||||
case ir::Opcode::Store: {
|
||||
auto& store = static_cast<const ir::StoreInst&>(inst);
|
||||
auto dst = slots.find(store.ptr());
|
||||
auto dst = slots.find(store.GetPtr());
|
||||
if (dst == slots.end()) {
|
||||
throw std::runtime_error(
|
||||
FormatError("mir", "暂不支持对非栈变量地址进行写入"));
|
||||
}
|
||||
EmitValueToReg(store.value(), PhysReg::W8, slots, block);
|
||||
EmitValueToReg(store.GetValue(), PhysReg::W8, slots, block);
|
||||
block.Append(Opcode::StoreStack,
|
||||
{Operand::Reg(PhysReg::W8), Operand::FrameIndex(dst->second)});
|
||||
return;
|
||||
}
|
||||
case ir::Opcode::Load: {
|
||||
auto& load = static_cast<const ir::LoadInst&>(inst);
|
||||
auto src = slots.find(load.ptr());
|
||||
auto src = slots.find(load.GetPtr());
|
||||
if (src == slots.end()) {
|
||||
throw std::runtime_error(
|
||||
FormatError("mir", "暂不支持对非栈变量地址进行读取"));
|
||||
@@ -68,8 +68,8 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
||||
case ir::Opcode::Add: {
|
||||
auto& bin = static_cast<const ir::BinaryInst&>(inst);
|
||||
int dst_slot = function.CreateFrameIndex();
|
||||
EmitValueToReg(bin.lhs(), PhysReg::W8, slots, block);
|
||||
EmitValueToReg(bin.rhs(), PhysReg::W9, slots, block);
|
||||
EmitValueToReg(bin.GetLhs(), PhysReg::W8, slots, block);
|
||||
EmitValueToReg(bin.GetRhs(), PhysReg::W9, slots, block);
|
||||
block.Append(Opcode::AddRR, {Operand::Reg(PhysReg::W8),
|
||||
Operand::Reg(PhysReg::W8),
|
||||
Operand::Reg(PhysReg::W9)});
|
||||
@@ -80,7 +80,7 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
||||
}
|
||||
case ir::Opcode::Ret: {
|
||||
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);
|
||||
return;
|
||||
}
|
||||
@@ -97,23 +97,23 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
||||
std::unique_ptr<MachineFunction> LowerToMIR(const ir::Module& module) {
|
||||
DefaultContext();
|
||||
|
||||
if (module.functions().size() != 1) {
|
||||
if (module.GetFunctions().size() != 1) {
|
||||
throw std::runtime_error(FormatError("mir", "暂不支持多个函数"));
|
||||
}
|
||||
|
||||
const auto& func = *module.functions().front();
|
||||
if (func.name() != "main") {
|
||||
const auto& func = *module.GetFunctions().front();
|
||||
if (func.GetName() != "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;
|
||||
const auto* entry = func.entry();
|
||||
const auto* entry = func.GetEntry();
|
||||
if (!entry) {
|
||||
throw std::runtime_error(FormatError("mir", "IR 函数缺少入口基本块"));
|
||||
}
|
||||
|
||||
for (const auto& inst : entry->instructions()) {
|
||||
for (const auto& inst : entry->GetInstructions()) {
|
||||
LowerInstruction(*inst, *machine_func, slots);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,14 +16,14 @@ int MachineFunction::CreateFrameIndex(int size) {
|
||||
return index;
|
||||
}
|
||||
|
||||
FrameSlot& MachineFunction::frame_slot(int index) {
|
||||
FrameSlot& MachineFunction::GetFrameSlot(int index) {
|
||||
if (index < 0 || index >= static_cast<int>(frame_slots_.size())) {
|
||||
throw std::runtime_error(FormatError("mir", "非法 FrameIndex"));
|
||||
}
|
||||
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())) {
|
||||
throw std::runtime_error(FormatError("mir", "非法 FrameIndex"));
|
||||
}
|
||||
|
||||
@@ -23,9 +23,10 @@ bool IsAllowedReg(PhysReg reg) {
|
||||
} // namespace
|
||||
|
||||
void RunRegAlloc(MachineFunction& function) {
|
||||
for (const auto& inst : function.entry().instructions()) {
|
||||
for (const auto& operand : inst.operands()) {
|
||||
if (operand.kind() == Operand::Kind::Reg && !IsAllowedReg(operand.reg())) {
|
||||
for (const auto& inst : function.GetEntry().GetInstructions()) {
|
||||
for (const auto& operand : inst.GetOperands()) {
|
||||
if (operand.GetKind() == Operand::Kind::Reg &&
|
||||
!IsAllowedReg(operand.GetReg())) {
|
||||
throw std::runtime_error(FormatError("mir", "寄存器分配失败"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user