From 8aa5ba692f16267ae9c73d826c6497abb4bde9dc Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Thu, 7 Aug 2025 01:34:00 +0800 Subject: [PATCH] =?UTF-8?q?[midend]=E5=88=9D=E6=AD=A5=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=86=85=E5=AD=98=E6=B3=84=E6=BC=8F=E9=97=AE=E9=A2=98(?= =?UTF-8?q?=E4=BB=8D=E7=84=B6=E5=89=A9=E4=BD=9911=E5=A4=84)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/include/midend/IR.h | 40 ++++++++++++ src/midend/IR.cpp | 135 ++++++++++++++++++++++++++++++++++++++++ src/sysyc.cpp | 11 ++++ 3 files changed, 186 insertions(+) diff --git a/src/include/midend/IR.h b/src/include/midend/IR.h index 73a93cc..bc010c9 100644 --- a/src/include/midend/IR.h +++ b/src/include/midend/IR.h @@ -20,6 +20,10 @@ #include namespace sysy { + +// Global cleanup function to release all statically allocated IR objects +void cleanupIRPools(); + /** * \defgroup type Types * @brief Sysy的类型系统 @@ -95,6 +99,9 @@ class PointerType : public Type { public: static PointerType* get(Type *baseType); ///< 获取指向baseType的Pointer类型 + + // Cleanup method to release all cached pointer types (call at program exit) + static void cleanup(); public: Type* getBaseType() const { return baseType; } ///< 获取指向的类型 @@ -112,6 +119,9 @@ class FunctionType : public Type { public: /// 获取返回值类型为returnType, 形参类型列表为paramTypes的Function类型 static FunctionType* get(Type *returnType, const std::vector ¶mTypes = {}); + + // Cleanup method to release all cached function types (call at program exit) + static void cleanup(); public: Type* getReturnType() const { return returnType; } ///< 获取返回值类信息 @@ -124,6 +134,9 @@ class ArrayType : public Type { // elements:数组的元素类型 (例如,int[3] 的 elementType 是 int) // numElements:该维度的大小 (例如,int[3] 的 numElements 是 3) static ArrayType *get(Type *elementType, unsigned numElements); + + // Cleanup method to release all cached array types (call at program exit) + static void cleanup(); Type *getElementType() const { return elementType; } unsigned getNumElements() const { return numElements; } @@ -367,6 +380,9 @@ public: // Static factory method to get a canonical ConstantValue from the pool static ConstantValue* get(Type* type, ConstantValVariant val); + + // Cleanup method to release all cached constants (call at program exit) + static void cleanup(); // Helper methods to access constant values with appropriate casting int getInt() const { @@ -474,6 +490,9 @@ protected: public: static UndefinedValue* get(Type* type); + + // Cleanup method to release all cached undefined values (call at program exit) + static void cleanup(); size_t hash() const override { return std::hash{}(getType()); @@ -632,6 +651,10 @@ public: } } ///< 移除指定位置的指令 iterator moveInst(iterator sourcePos, iterator targetPos, BasicBlock *block); + + /// 清理基本块中的所有使用关系 + void cleanup(); + void print(std::ostream& os) const; }; @@ -667,6 +690,9 @@ class User : public Value { } ///< 增加多个操作数 void replaceOperand(unsigned index, Value *value); ///< 替换操作数 void setOperand(unsigned index, Value *value); ///< 设置操作数 + + /// 清理用户的所有操作数使用关系 + void cleanup(); }; /*! @@ -1321,6 +1347,10 @@ public: public: Function* getParent() const { return func; } int getIndex() const { return index; } + + /// 清理参数的使用关系 + void cleanup(); + void print(std::ostream& os) const; }; @@ -1399,6 +1429,10 @@ protected: blocks.emplace_front(block); return block; } + + /// 清理函数中的所有使用关系 + void cleanup(); + void print(std::ostream& os) const; }; @@ -1554,6 +1588,9 @@ class SymbolTable { bool isInGlobalScope() const; ///< 是否位于全局作用域 void enterGlobalScope(); ///< 进入全局作用域 bool isCurNodeNull() { return curNode == nullptr; } + + /// 清理符号表中的所有内容 + void cleanup(); }; //! IR unit for representing a SysY compile unit @@ -1639,6 +1676,9 @@ class Module { bool isInGlobalArea() const { return variableTable.isInGlobalScope(); } ///< 是否位于全局作用域 + /// 清理模块中的所有对象,包括函数、基本块、指令等 + void cleanup(); + void print(std::ostream& os) const; }; diff --git a/src/midend/IR.cpp b/src/midend/IR.cpp index fffab0c..89e44de 100644 --- a/src/midend/IR.cpp +++ b/src/midend/IR.cpp @@ -25,6 +25,18 @@ inline std::string getMachineCode(float fval) { */ namespace sysy { +// Global cleanup function implementation +void cleanupIRPools() { + // Clean up the main memory pools that cause leaks + ConstantValue::cleanup(); + UndefinedValue::cleanup(); + + // Note: Type pools (PointerType, FunctionType, ArrayType) use unique_ptr + // and will be automatically cleaned up when the program exits. + // For more thorough cleanup during program execution, consider refactoring + // to use singleton pattern with explicit cleanup methods. +} + /*相关打印函数*/ template @@ -206,6 +218,12 @@ PointerType* PointerType::get(Type *baseType) { return result.first->second.get(); } +void PointerType::cleanup() { + // Note: Due to static variable scoping, we can't directly access + // the static map here. The cleanup will happen when the program exits. + // For more thorough cleanup, consider using a singleton pattern. +} + FunctionType*FunctionType::get(Type *returnType, const std::vector ¶mTypes) { static std::set> functionTypes; auto iter = @@ -225,6 +243,12 @@ FunctionType*FunctionType::get(Type *returnType, const std::vector ¶ return result.first->get(); } +void FunctionType::cleanup() { + // Note: Due to static variable scoping, we can't directly access + // the static set here. The cleanup will happen when the program exits. + // For more thorough cleanup, consider using a singleton pattern. +} + ArrayType *ArrayType::get(Type *elementType, unsigned numElements) { static std::set> arrayTypes; auto iter = std::find_if(arrayTypes.begin(), arrayTypes.end(), [&](const std::unique_ptr &type) -> bool { @@ -239,6 +263,12 @@ ArrayType *ArrayType::get(Type *elementType, unsigned numElements) { return result.first->get(); } +void ArrayType::cleanup() { + // Note: Due to static variable scoping, we can't directly access + // the static set here. The cleanup will happen when the program exits. + // For more thorough cleanup, consider using a singleton pattern. +} + void Argument::print(std::ostream& os) const { os << *getType() << " %" << getName(); } @@ -464,6 +494,13 @@ ConstantValue* ConstantValue::get(Type* type, ConstantValVariant val) { return newConstant; } +void ConstantValue::cleanup() { + for (auto& pair : mConstantPool) { + delete pair.second; + } + mConstantPool.clear(); +} + ConstantInteger* ConstantInteger::get(Type* type, int val) { return dynamic_cast(ConstantValue::get(type, val)); } @@ -485,6 +522,13 @@ UndefinedValue* UndefinedValue::get(Type* type) { return newUndef; } +void UndefinedValue::cleanup() { + for (auto& pair : UndefValues) { + delete pair.second; + } + UndefValues.clear(); +} + void ConstantValue::print(std::ostream &os) const { if(dynamic_cast(this)) { dynamic_cast(this)->print(os); @@ -1097,4 +1141,95 @@ void Module::print(std::ostream& os) const { } } +void Module::cleanup() { + // 清理所有函数中的使用关系 + for (auto& func : functions) { + if (func.second) { + func.second->cleanup(); + } + } + + for (auto& extFunc : externalFunctions) { + if (extFunc.second) { + extFunc.second->cleanup(); + } + } + + // 清理符号表 + variableTable.cleanup(); + + // 清理函数表 + functions.clear(); + externalFunctions.clear(); +} + +void Function::cleanup() { + // 清理所有基本块中的使用关系 + for (auto& block : blocks) { + if (block) { + block->cleanup(); + } + } + + // 清理参数列表中的使用关系 + for (auto arg : arguments) { + if (arg) { + arg->cleanup(); + } + } + + // 清理基本块列表 + blocks.clear(); + arguments.clear(); + callees.clear(); +} + +void BasicBlock::cleanup() { + // 清理所有指令中的使用关系 + for (auto& inst : instructions) { + if (inst) { + inst->cleanup(); + } + } + + // 清理指令列表 + instructions.clear(); + + // 清理前驱后继关系 + predecessors.clear(); + successors.clear(); +} + +void User::cleanup() { + // 清理所有操作数的使用关系 + for (auto& operand : operands) { + if (operand && operand->getValue()) { + operand->getValue()->removeUse(operand); + } + } + + // 清理操作数列表 + operands.clear(); +} + +void SymbolTable::cleanup() { + // 清理全局变量和常量 + globals.clear(); + globalconsts.clear(); + + // 清理符号表节点 + nodeList.clear(); + + // 重置当前节点 + curNode = nullptr; + + // 清理变量索引 + variableIndex.clear(); +} + +void Argument::cleanup() { + // Argument继承自Value,清理其使用列表 + uses.clear(); +} + } // namespace sysy diff --git a/src/sysyc.cpp b/src/sysyc.cpp index be17fd3..b946934 100644 --- a/src/sysyc.cpp +++ b/src/sysyc.cpp @@ -110,6 +110,7 @@ int main(int argc, char **argv) { // 如果指定停止在 AST 阶段,则打印并退出 if (argStopAfter == "ast") { cout << moduleAST->toStringTree(true) << '\n'; + sysy::cleanupIRPools(); // 清理内存池 return EXIT_SUCCESS; } @@ -150,6 +151,8 @@ int main(int argc, char **argv) { ofstream fout(argOutputFilename); if (not fout.is_open()) { cerr << "Failed to open output file: " << argOutputFilename << endl; + moduleIR->cleanup(); // 清理模块 + sysy::cleanupIRPools(); // 清理内存池 return EXIT_FAILURE; } moduleIR->print(fout); @@ -158,6 +161,8 @@ int main(int argc, char **argv) { // 输出到标准输出 moduleIR->print(cout); } + moduleIR->cleanup(); // 清理模块 + sysy::cleanupIRPools(); // 清理内存池 return EXIT_SUCCESS; } @@ -178,6 +183,8 @@ int main(int argc, char **argv) { ofstream fout(argOutputFilename); if (not fout.is_open()) { cerr << "Failed to open output file: " << argOutputFilename << endl; + moduleIR->cleanup(); // 清理模块 + sysy::cleanupIRPools(); // 清理内存池 return EXIT_FAILURE; } fout << asmCode << endl; @@ -185,6 +192,8 @@ int main(int argc, char **argv) { } else { cout << asmCode << endl; } + moduleIR->cleanup(); // 清理模块 + sysy::cleanupIRPools(); // 清理内存池 return EXIT_SUCCESS; } @@ -193,5 +202,7 @@ int main(int argc, char **argv) { cout << "Compilation completed. No output specified (neither -s nor -S). Exiting.\n"; // return EXIT_SUCCESS; // 或者这里调用一个链接器生成可执行文件 + moduleIR->cleanup(); // 清理模块 + sysy::cleanupIRPools(); // 清理内存池 return EXIT_SUCCESS; } \ No newline at end of file