// 极简 IR 定义:当前只支撑 i32 和加法,演示用。 // 可在此基础上扩展更多类型/指令 #pragma once #include #include #include #include #include #include #include namespace ir { class Type; class ConstantInt; class Instruction; class BasicBlock; class Function; // IR 上下文:集中管理类型、常量等共享资源,便于复用与扩展。 class Context { public: Context() = default; ~Context(); const std::shared_ptr& Void(); const std::shared_ptr& Int32(); const std::shared_ptr& PtrInt32(); // 去重创建 i32 常量。 ConstantInt* GetConstInt(int v); std::string NextTemp(); private: std::shared_ptr void_; std::shared_ptr int32_; std::shared_ptr ptr_i32_; std::unordered_map> const_ints_; int temp_index_ = -1; }; class Type { public: enum class Kind { Void, Int32, PtrInt32 }; explicit Type(Kind k); Kind GetKind() const; bool IsVoid() const; bool IsInt32() const; bool IsPtrInt32() const; private: Kind kind_; }; class Value { public: Value(std::shared_ptr ty, std::string name); virtual ~Value() = default; const std::shared_ptr& GetType() const; const std::string& GetName() const; void SetName(std::string n); void AddUser(Instruction* user); const std::vector& GetUsers() const; protected: std::shared_ptr type_; std::string name_; std::vector users_; }; class ConstantInt : public Value { public: ConstantInt(std::shared_ptr ty, int v); int GetValue() const { return value_; } private: int value_{}; }; // 后续还需要扩展更多指令类型。 enum class Opcode { Add, Sub, Mul, Alloca, Load, Store, Ret }; class Instruction : public Value { public: Instruction(Opcode op, std::shared_ptr ty, std::string name = ""); Opcode GetOpcode() const; bool IsTerminator() const; BasicBlock* GetParent() const; void SetParent(BasicBlock* parent); private: Opcode opcode_; BasicBlock* parent_ = nullptr; }; class BinaryInst : public Instruction { public: BinaryInst(Opcode op, std::shared_ptr ty, Value* lhs, Value* rhs, std::string name); Value* GetLhs() const; Value* GetRhs() const; private: Value* lhs_; Value* rhs_; }; class ReturnInst : public Instruction { public: ReturnInst(std::shared_ptr void_ty, Value* val); Value* GetValue() const; private: Value* value_; }; class AllocaInst : public Instruction { public: AllocaInst(std::shared_ptr ptr_ty, std::string name); }; class LoadInst : public Instruction { public: LoadInst(std::shared_ptr val_ty, Value* ptr, std::string name); Value* GetPtr() const; private: Value* ptr_; }; class StoreInst : public Instruction { public: StoreInst(std::shared_ptr void_ty, Value* val, Value* ptr); Value* GetValue() const; Value* GetPtr() const; private: Value* value_; Value* ptr_; }; class BasicBlock { public: explicit BasicBlock(std::string name); const std::string& GetName() const; Function* GetParent() const; void SetParent(Function* parent); bool HasTerminator() const; const std::vector>& GetInstructions() const; const std::vector& GetPredecessors() const; const std::vector& GetSuccessors() const; template T* Append(Args&&... args) { if (HasTerminator()) { throw std::runtime_error("BasicBlock 已有 terminator,不能继续追加指令: " + name_); } auto inst = std::make_unique(std::forward(args)...); auto* ptr = inst.get(); ptr->SetParent(this); instructions_.push_back(std::move(inst)); return ptr; } private: std::string name_; Function* parent_ = nullptr; std::vector> instructions_; std::vector predecessors_; std::vector successors_; }; class Function : public Value { public: // 允许显式指定返回类型,便于后续扩展多种函数签名。 Function(std::string name, std::shared_ptr ret_type); BasicBlock* CreateBlock(const std::string& name); BasicBlock* GetEntry(); const BasicBlock* GetEntry() const; const std::vector>& GetBlocks() const; private: BasicBlock* entry_ = nullptr; std::vector> blocks_; }; class Module { public: Module() = default; Context& GetContext(); const Context& GetContext() const; // 创建函数时显式传入返回类型,便于在 IRGen 中根据语法树信息选择类型。 Function* CreateFunction(const std::string& name, std::shared_ptr ret_type); const std::vector>& GetFunctions() const; private: Context context_; std::vector> functions_; }; class IRBuilder { public: IRBuilder(Context& ctx, BasicBlock* bb); void SetInsertPoint(BasicBlock* bb); BasicBlock* GetInsertBlock() const; // 构造常量、二元运算、返回指令的最小集合。 ConstantInt* CreateConstInt(int v); BinaryInst* CreateBinary(Opcode op, Value* lhs, Value* rhs, const std::string& name); BinaryInst* CreateAdd(Value* lhs, Value* rhs, const std::string& name); AllocaInst* CreateAllocaI32(const std::string& name); LoadInst* CreateLoad(Value* ptr, const std::string& name); StoreInst* CreateStore(Value* val, Value* ptr); ReturnInst* CreateRet(Value* v); private: Context& ctx_; BasicBlock* insert_block_; }; class IRPrinter { public: void Print(const Module& module, std::ostream& os); }; } // namespace ir