// IR 构建工具: // - 管理插入点(当前基本块/位置) // - 提供创建各类指令的便捷接口,降低 IRGen 复杂度 #include "ir/IR.h" #include namespace ir { namespace { bool IsArithmeticType(const std::shared_ptr& ty) { return ty && ty->kind() == Type::Kind::Int32; } bool IsPtrInt32Type(const std::shared_ptr& ty) { return ty && ty->kind() == Type::Kind::PtrInt32; } } // namespace IRBuilder::IRBuilder(BasicBlock* bb) : insertBlock_(bb) {} void IRBuilder::SetInsertPoint(BasicBlock* bb) { insertBlock_ = bb; } BasicBlock* IRBuilder::GetInsertBlock() const { return insertBlock_; } ConstantInt* IRBuilder::CreateConstInt(int v) { // 常量不需要挂在基本块里,由 Context 负责去重与生命周期。 return DefaultContext().GetConstInt(v); } BinaryInst* IRBuilder::CreateBinary(Opcode op, Value* lhs, Value* rhs, const std::string& name) { if (!insertBlock_) { throw std::runtime_error("IRBuilder 未设置插入点"); } if (!lhs) { throw std::runtime_error("IRBuilder::CreateBinary 缺少 lhs"); } if (!rhs) { throw std::runtime_error("IRBuilder::CreateBinary 缺少 rhs"); } if (op != Opcode::Add) { throw std::runtime_error("IRBuilder::CreateBinary 当前只支持 Add"); } if (!lhs->type() || !rhs->type() || lhs->type()->kind() != rhs->type()->kind()) { throw std::runtime_error("IRBuilder::CreateBinary 操作数类型不匹配"); } if (!IsArithmeticType(lhs->type())) { throw std::runtime_error("IRBuilder::CreateBinary 当前只支持 i32 二元运算"); } return insertBlock_->Append(op, lhs->type(), lhs, rhs, name); } BinaryInst* IRBuilder::CreateAdd(Value* lhs, Value* rhs, const std::string& name) { return CreateBinary(Opcode::Add, lhs, rhs, name); } AllocaInst* IRBuilder::CreateAllocaI32(const std::string& name) { if (!insertBlock_) { throw std::runtime_error("IRBuilder 未设置插入点"); } return insertBlock_->Append(name); } LoadInst* IRBuilder::CreateLoad(Value* ptr, const std::string& name) { if (!insertBlock_) { throw std::runtime_error("IRBuilder 未设置插入点"); } if (!ptr) { throw std::runtime_error("IRBuilder::CreateLoad 缺少 ptr"); } if (!IsPtrInt32Type(ptr->type())) { throw std::runtime_error("IRBuilder::CreateLoad 当前只支持从 i32* 加载"); } return insertBlock_->Append(ptr, name); } StoreInst* IRBuilder::CreateStore(Value* val, Value* ptr) { if (!insertBlock_) { throw std::runtime_error("IRBuilder 未设置插入点"); } if (!val) { throw std::runtime_error("IRBuilder::CreateStore 缺少 val"); } if (!ptr) { throw std::runtime_error("IRBuilder::CreateStore 缺少 ptr"); } if (!IsArithmeticType(val->type())) { throw std::runtime_error("IRBuilder::CreateStore 当前只支持存储 i32"); } if (!IsPtrInt32Type(ptr->type())) { throw std::runtime_error("IRBuilder::CreateStore 当前只支持写入 i32*"); } return insertBlock_->Append(val, ptr); } ReturnInst* IRBuilder::CreateRet(Value* v) { if (!insertBlock_) { throw std::runtime_error("IRBuilder 未设置插入点"); } if (!v) { throw std::runtime_error("IRBuilder::CreateRet 缺少返回值"); } return insertBlock_->Append(v); } } // namespace ir