[midend]初步修复内存泄漏问题(仍然剩余11处)
This commit is contained in:
@ -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 *> ¶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<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;
|
||||
};
|
||||
|
||||
|
||||
@ -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 *> ¶mTypes) {
|
||||
static std::set<std::unique_ptr<FunctionType>> functionTypes;
|
||||
auto iter =
|
||||
@ -225,6 +243,12 @@ FunctionType*FunctionType::get(Type *returnType, const std::vector<Type *> ¶
|
||||
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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user