[midend]初步修复内存泄漏问题(仍然剩余11处)
This commit is contained in:
@@ -20,6 +20,10 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
namespace sysy {
|
namespace sysy {
|
||||||
|
|
||||||
|
// Global cleanup function to release all statically allocated IR objects
|
||||||
|
void cleanupIRPools();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \defgroup type Types
|
* \defgroup type Types
|
||||||
* @brief Sysy的类型系统
|
* @brief Sysy的类型系统
|
||||||
@@ -95,6 +99,9 @@ class PointerType : public Type {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
static PointerType* get(Type *baseType); ///< 获取指向baseType的Pointer类型
|
static PointerType* get(Type *baseType); ///< 获取指向baseType的Pointer类型
|
||||||
|
|
||||||
|
// Cleanup method to release all cached pointer types (call at program exit)
|
||||||
|
static void cleanup();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Type* getBaseType() const { return baseType; } ///< 获取指向的类型
|
Type* getBaseType() const { return baseType; } ///< 获取指向的类型
|
||||||
@@ -112,6 +119,9 @@ class FunctionType : public Type {
|
|||||||
public:
|
public:
|
||||||
/// 获取返回值类型为returnType, 形参类型列表为paramTypes的Function类型
|
/// 获取返回值类型为returnType, 形参类型列表为paramTypes的Function类型
|
||||||
static FunctionType* get(Type *returnType, const std::vector<Type *> ¶mTypes = {});
|
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:
|
public:
|
||||||
Type* getReturnType() const { return returnType; } ///< 获取返回值类信息
|
Type* getReturnType() const { return returnType; } ///< 获取返回值类信息
|
||||||
@@ -124,6 +134,9 @@ class ArrayType : public Type {
|
|||||||
// elements:数组的元素类型 (例如,int[3] 的 elementType 是 int)
|
// elements:数组的元素类型 (例如,int[3] 的 elementType 是 int)
|
||||||
// numElements:该维度的大小 (例如,int[3] 的 numElements 是 3)
|
// numElements:该维度的大小 (例如,int[3] 的 numElements 是 3)
|
||||||
static ArrayType *get(Type *elementType, unsigned numElements);
|
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; }
|
Type *getElementType() const { return elementType; }
|
||||||
unsigned getNumElements() const { return numElements; }
|
unsigned getNumElements() const { return numElements; }
|
||||||
@@ -367,6 +380,9 @@ public:
|
|||||||
|
|
||||||
// Static factory method to get a canonical ConstantValue from the pool
|
// Static factory method to get a canonical ConstantValue from the pool
|
||||||
static ConstantValue* get(Type* type, ConstantValVariant val);
|
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
|
// Helper methods to access constant values with appropriate casting
|
||||||
int getInt() const {
|
int getInt() const {
|
||||||
@@ -474,6 +490,9 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
static UndefinedValue* get(Type* type);
|
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 {
|
size_t hash() const override {
|
||||||
return std::hash<Type*>{}(getType());
|
return std::hash<Type*>{}(getType());
|
||||||
@@ -632,6 +651,10 @@ public:
|
|||||||
}
|
}
|
||||||
} ///< 移除指定位置的指令
|
} ///< 移除指定位置的指令
|
||||||
iterator moveInst(iterator sourcePos, iterator targetPos, BasicBlock *block);
|
iterator moveInst(iterator sourcePos, iterator targetPos, BasicBlock *block);
|
||||||
|
|
||||||
|
/// 清理基本块中的所有使用关系
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
void print(std::ostream& os) const;
|
void print(std::ostream& os) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -667,6 +690,9 @@ class User : public Value {
|
|||||||
} ///< 增加多个操作数
|
} ///< 增加多个操作数
|
||||||
void replaceOperand(unsigned index, Value *value); ///< 替换操作数
|
void replaceOperand(unsigned index, Value *value); ///< 替换操作数
|
||||||
void setOperand(unsigned index, Value *value); ///< 设置操作数
|
void setOperand(unsigned index, Value *value); ///< 设置操作数
|
||||||
|
|
||||||
|
/// 清理用户的所有操作数使用关系
|
||||||
|
void cleanup();
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -1321,6 +1347,10 @@ public:
|
|||||||
public:
|
public:
|
||||||
Function* getParent() const { return func; }
|
Function* getParent() const { return func; }
|
||||||
int getIndex() const { return index; }
|
int getIndex() const { return index; }
|
||||||
|
|
||||||
|
/// 清理参数的使用关系
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
void print(std::ostream& os) const;
|
void print(std::ostream& os) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1399,6 +1429,10 @@ protected:
|
|||||||
blocks.emplace_front(block);
|
blocks.emplace_front(block);
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 清理函数中的所有使用关系
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
void print(std::ostream& os) const;
|
void print(std::ostream& os) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1554,6 +1588,9 @@ class SymbolTable {
|
|||||||
bool isInGlobalScope() const; ///< 是否位于全局作用域
|
bool isInGlobalScope() const; ///< 是否位于全局作用域
|
||||||
void enterGlobalScope(); ///< 进入全局作用域
|
void enterGlobalScope(); ///< 进入全局作用域
|
||||||
bool isCurNodeNull() { return curNode == nullptr; }
|
bool isCurNodeNull() { return curNode == nullptr; }
|
||||||
|
|
||||||
|
/// 清理符号表中的所有内容
|
||||||
|
void cleanup();
|
||||||
};
|
};
|
||||||
|
|
||||||
//! IR unit for representing a SysY compile unit
|
//! IR unit for representing a SysY compile unit
|
||||||
@@ -1639,6 +1676,9 @@ class Module {
|
|||||||
|
|
||||||
bool isInGlobalArea() const { return variableTable.isInGlobalScope(); } ///< 是否位于全局作用域
|
bool isInGlobalArea() const { return variableTable.isInGlobalScope(); } ///< 是否位于全局作用域
|
||||||
|
|
||||||
|
/// 清理模块中的所有对象,包括函数、基本块、指令等
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
void print(std::ostream& os) const;
|
void print(std::ostream& os) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,18 @@ inline std::string getMachineCode(float fval) {
|
|||||||
*/
|
*/
|
||||||
namespace sysy {
|
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>
|
template <typename T>
|
||||||
@@ -206,6 +218,12 @@ PointerType* PointerType::get(Type *baseType) {
|
|||||||
return result.first->second.get();
|
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) {
|
FunctionType*FunctionType::get(Type *returnType, const std::vector<Type *> ¶mTypes) {
|
||||||
static std::set<std::unique_ptr<FunctionType>> functionTypes;
|
static std::set<std::unique_ptr<FunctionType>> functionTypes;
|
||||||
auto iter =
|
auto iter =
|
||||||
@@ -225,6 +243,12 @@ FunctionType*FunctionType::get(Type *returnType, const std::vector<Type *> ¶
|
|||||||
return result.first->get();
|
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) {
|
ArrayType *ArrayType::get(Type *elementType, unsigned numElements) {
|
||||||
static std::set<std::unique_ptr<ArrayType>> arrayTypes;
|
static std::set<std::unique_ptr<ArrayType>> arrayTypes;
|
||||||
auto iter = std::find_if(arrayTypes.begin(), arrayTypes.end(), [&](const std::unique_ptr<ArrayType> &type) -> bool {
|
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();
|
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 {
|
void Argument::print(std::ostream& os) const {
|
||||||
os << *getType() << " %" << getName();
|
os << *getType() << " %" << getName();
|
||||||
}
|
}
|
||||||
@@ -464,6 +494,13 @@ ConstantValue* ConstantValue::get(Type* type, ConstantValVariant val) {
|
|||||||
return newConstant;
|
return newConstant;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConstantValue::cleanup() {
|
||||||
|
for (auto& pair : mConstantPool) {
|
||||||
|
delete pair.second;
|
||||||
|
}
|
||||||
|
mConstantPool.clear();
|
||||||
|
}
|
||||||
|
|
||||||
ConstantInteger* ConstantInteger::get(Type* type, int val) {
|
ConstantInteger* ConstantInteger::get(Type* type, int val) {
|
||||||
return dynamic_cast<ConstantInteger*>(ConstantValue::get(type, val));
|
return dynamic_cast<ConstantInteger*>(ConstantValue::get(type, val));
|
||||||
}
|
}
|
||||||
@@ -485,6 +522,13 @@ UndefinedValue* UndefinedValue::get(Type* type) {
|
|||||||
return newUndef;
|
return newUndef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UndefinedValue::cleanup() {
|
||||||
|
for (auto& pair : UndefValues) {
|
||||||
|
delete pair.second;
|
||||||
|
}
|
||||||
|
UndefValues.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void ConstantValue::print(std::ostream &os) const {
|
void ConstantValue::print(std::ostream &os) const {
|
||||||
if(dynamic_cast<const ConstantInteger*>(this)) {
|
if(dynamic_cast<const ConstantInteger*>(this)) {
|
||||||
dynamic_cast<const ConstantInteger*>(this)->print(os);
|
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
|
} // namespace sysy
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ int main(int argc, char **argv) {
|
|||||||
// 如果指定停止在 AST 阶段,则打印并退出
|
// 如果指定停止在 AST 阶段,则打印并退出
|
||||||
if (argStopAfter == "ast") {
|
if (argStopAfter == "ast") {
|
||||||
cout << moduleAST->toStringTree(true) << '\n';
|
cout << moduleAST->toStringTree(true) << '\n';
|
||||||
|
sysy::cleanupIRPools(); // 清理内存池
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,6 +151,8 @@ int main(int argc, char **argv) {
|
|||||||
ofstream fout(argOutputFilename);
|
ofstream fout(argOutputFilename);
|
||||||
if (not fout.is_open()) {
|
if (not fout.is_open()) {
|
||||||
cerr << "Failed to open output file: " << argOutputFilename << endl;
|
cerr << "Failed to open output file: " << argOutputFilename << endl;
|
||||||
|
moduleIR->cleanup(); // 清理模块
|
||||||
|
sysy::cleanupIRPools(); // 清理内存池
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
moduleIR->print(fout);
|
moduleIR->print(fout);
|
||||||
@@ -158,6 +161,8 @@ int main(int argc, char **argv) {
|
|||||||
// 输出到标准输出
|
// 输出到标准输出
|
||||||
moduleIR->print(cout);
|
moduleIR->print(cout);
|
||||||
}
|
}
|
||||||
|
moduleIR->cleanup(); // 清理模块
|
||||||
|
sysy::cleanupIRPools(); // 清理内存池
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -178,6 +183,8 @@ int main(int argc, char **argv) {
|
|||||||
ofstream fout(argOutputFilename);
|
ofstream fout(argOutputFilename);
|
||||||
if (not fout.is_open()) {
|
if (not fout.is_open()) {
|
||||||
cerr << "Failed to open output file: " << argOutputFilename << endl;
|
cerr << "Failed to open output file: " << argOutputFilename << endl;
|
||||||
|
moduleIR->cleanup(); // 清理模块
|
||||||
|
sysy::cleanupIRPools(); // 清理内存池
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
fout << asmCode << endl;
|
fout << asmCode << endl;
|
||||||
@@ -185,6 +192,8 @@ int main(int argc, char **argv) {
|
|||||||
} else {
|
} else {
|
||||||
cout << asmCode << endl;
|
cout << asmCode << endl;
|
||||||
}
|
}
|
||||||
|
moduleIR->cleanup(); // 清理模块
|
||||||
|
sysy::cleanupIRPools(); // 清理内存池
|
||||||
return EXIT_SUCCESS;
|
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";
|
cout << "Compilation completed. No output specified (neither -s nor -S). Exiting.\n";
|
||||||
// return EXIT_SUCCESS; // 或者这里调用一个链接器生成可执行文件
|
// return EXIT_SUCCESS; // 或者这里调用一个链接器生成可执行文件
|
||||||
|
|
||||||
|
moduleIR->cleanup(); // 清理模块
|
||||||
|
sysy::cleanupIRPools(); // 清理内存池
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user