[midend]初步修复内存泄漏问题(仍然剩余11处)

This commit is contained in:
rain2133
2025-08-07 01:34:00 +08:00
parent d732800149
commit 8aa5ba692f
3 changed files with 186 additions and 0 deletions

View File

@ -20,6 +20,10 @@
#include <algorithm>
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<Type *> &paramTypes = {});
// 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<Type*>{}(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;
};

View File

@ -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 <typename T>
@ -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<Type *> &paramTypes) {
static std::set<std::unique_ptr<FunctionType>> functionTypes;
auto iter =
@ -225,6 +243,12 @@ FunctionType*FunctionType::get(Type *returnType, const std::vector<Type *> &para
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<std::unique_ptr<ArrayType>> arrayTypes;
auto iter = std::find_if(arrayTypes.begin(), arrayTypes.end(), [&](const std::unique_ptr<ArrayType> &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<ConstantInteger*>(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<const ConstantInteger*>(this)) {
dynamic_cast<const ConstantInteger*>(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

View File

@ -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;
}