// IR 构建工具: // - 管理插入点(当前基本块/位置) // - 提供创建各类指令的便捷接口,降低 IRGen 复杂度 #include "ir/IR.h" #include #include "utils/Log.h" namespace ir { IRBuilder::IRBuilder(Context& ctx, BasicBlock* bb) : ctx_(ctx), insert_block_(bb) {} void IRBuilder::SetInsertPoint(BasicBlock* bb) { insert_block_ = bb; } BasicBlock* IRBuilder::GetInsertBlock() const { return insert_block_; } ConstantInt* IRBuilder::CreateConstInt(int v) { // 常量不需要挂在基本块里,由 Context 负责去重与生命周期。 return ctx_.GetConstInt(v); } ConstantFloat* IRBuilder::CreateConstFloat(float v) { // 常量不需要挂在基本块里,由 Context 负责去重与生命周期。 return ctx_.GetConstFloat(v); } BinaryInst* IRBuilder::CreateBinary(Opcode op, Value* lhs, Value* rhs, const std::string& name) { if (!insert_block_) { throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); } if (!lhs) { throw std::runtime_error( FormatError("ir", "IRBuilder::CreateBinary 缺少 lhs")); } if (!rhs) { throw std::runtime_error( FormatError("ir", "IRBuilder::CreateBinary 缺少 rhs")); } return insert_block_->Append(op, lhs->GetType(), lhs, rhs, name); } BinaryInst* IRBuilder::CreateAdd(Value* lhs, Value* rhs, const std::string& name) { return CreateBinary(Opcode::Add, lhs, rhs, name); } BinaryInst* IRBuilder::CreateSub(Value* lhs, Value* rhs, const std::string& name) { return CreateBinary(Opcode::Sub, lhs, rhs, name); } BinaryInst* IRBuilder::CreateMul(Value* lhs, Value* rhs, const std::string& name) { return CreateBinary(Opcode::Mul, lhs, rhs, name); } BinaryInst* IRBuilder::CreateDiv(Value* lhs, Value* rhs, const std::string& name) { return CreateBinary(Opcode::Div, lhs, rhs, name); } BinaryInst* IRBuilder::CreateMod(Value* lhs, Value* rhs, const std::string& name) { return CreateBinary(Opcode::Mod, lhs, rhs, name); } BinaryInst* IRBuilder::CreateFAdd(Value* lhs, Value* rhs, const std::string& name) { return CreateBinary(Opcode::FAdd, lhs, rhs, name); } BinaryInst* IRBuilder::CreateFSub(Value* lhs, Value* rhs, const std::string& name) { return CreateBinary(Opcode::FSub, lhs, rhs, name); } BinaryInst* IRBuilder::CreateFMul(Value* lhs, Value* rhs, const std::string& name) { return CreateBinary(Opcode::FMul, lhs, rhs, name); } BinaryInst* IRBuilder::CreateFDiv(Value* lhs, Value* rhs, const std::string& name) { return CreateBinary(Opcode::FDiv, lhs, rhs, name); } BinaryInst* IRBuilder::CreateICmp(Opcode op, Value* lhs, Value* rhs, const std::string& name) { if (!insert_block_) { throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); } return insert_block_->Append(op, Type::GetInt32Type(), lhs, rhs, name); } BinaryInst* IRBuilder::CreateFCmp(Opcode op, Value* lhs, Value* rhs, const std::string& name) { if (!insert_block_) { throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); } return insert_block_->Append(op, Type::GetInt32Type(), lhs, rhs, name); } AllocaInst* IRBuilder::CreateAlloca(std::shared_ptr ty, const std::string& name) { if (!insert_block_) { throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); } return insert_block_->Append(ty, name); } AllocaInst* IRBuilder::CreateAllocaI32(const std::string& name) { return CreateAlloca(Type::GetPtrInt32Type(), name); } LoadInst* IRBuilder::CreateLoad(Value* ptr, const std::string& name) { if (!insert_block_) { throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); } if (!ptr) { throw std::runtime_error( FormatError("ir", "IRBuilder::CreateLoad 缺少 ptr")); } std::shared_ptr val_ty; if (ptr->GetType()->IsPtrInt32()) { val_ty = Type::GetInt32Type(); } else if (ptr->GetType()->IsPtrFloat()) { val_ty = Type::GetFloatType(); } else { throw std::runtime_error(FormatError("ir", "LoadInst 不支持的指针类型")); } return insert_block_->Append(val_ty, ptr, name); } StoreInst* IRBuilder::CreateStore(Value* val, Value* ptr) { if (!insert_block_) { throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); } if (!val) { throw std::runtime_error( FormatError("ir", "IRBuilder::CreateStore 缺少 val")); } if (!ptr) { throw std::runtime_error( FormatError("ir", "IRBuilder::CreateStore 缺少 ptr")); } return insert_block_->Append(Type::GetVoidType(), val, ptr); } ReturnInst* IRBuilder::CreateRet(Value* v) { if (!insert_block_) { throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); } return insert_block_->Append(Type::GetVoidType(), v); } BranchInst* IRBuilder::CreateBr(BasicBlock* dest) { if (!insert_block_) { throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); } return insert_block_->Append(dest); } BranchInst* IRBuilder::CreateCondBr(Value* cond, BasicBlock* if_true, BasicBlock* if_false) { if (!insert_block_) { throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); } return insert_block_->Append(cond, if_true, if_false); } CallInst* IRBuilder::CreateCall(Function* func, const std::vector& args, const std::string& name) { if (!insert_block_) { throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); } return insert_block_->Append(func, args, name); } GetElementPtrInst* IRBuilder::CreateGEP(std::shared_ptr ptr_ty, Value* ptr, const std::vector& indices, const std::string& name) { if (!insert_block_) { throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); } return insert_block_->Append(ptr_ty, ptr, indices, name); } CastInst* IRBuilder::CreateZExt(Value* val, std::shared_ptr ty, const std::string& name) { if (!insert_block_) { throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); } return insert_block_->Append(Opcode::ZExt, ty, val, name); } CastInst* IRBuilder::CreateSIToFP(Value* val, std::shared_ptr ty, const std::string& name) { if (!insert_block_) { throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); } return insert_block_->Append(Opcode::SIToFP, ty, val, name); } CastInst* IRBuilder::CreateFPToSI(Value* val, std::shared_ptr ty, const std::string& name) { if (!insert_block_) { throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); } return insert_block_->Append(Opcode::FPToSI, ty, val, name); } PhiInst* IRBuilder::CreatePhi(std::shared_ptr ty, const std::string& name) { if (!insert_block_) { throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); } return insert_block_->Append(ty, name); } } // namespace ir