diff --git a/src/include/midend/IR.h b/src/include/midend/IR.h index b05b2ee..e6364a2 100644 --- a/src/include/midend/IR.h +++ b/src/include/midend/IR.h @@ -1584,6 +1584,8 @@ class SymbolTable { Value* getVariable(const std::string &name) const; ///< 根据名字name以及当前作用域获取变量 Value* addVariable(const std::string &name, Value *variable); ///< 添加变量 + void registerParameterName(const std::string &name); ///< 注册函数参数名字,避免alloca重名 + void addVariableDirectly(const std::string &name, Value *variable); ///< 直接添加变量到当前作用域,不重命名 std::vector>& getGlobals(); ///< 获取全局变量列表 const std::vector>& getConsts() const; ///< 获取全局常量列表 void enterNewScope(); ///< 进入新的作用域 @@ -1646,6 +1648,12 @@ class Module { void addVariable(const std::string &name, AllocaInst *variable) { variableTable.addVariable(name, variable); } ///< 添加变量 + void addVariableDirectly(const std::string &name, AllocaInst *variable) { + variableTable.addVariableDirectly(name, variable); + } ///< 直接添加变量到当前作用域,不重命名 + void registerParameterName(const std::string &name) { + variableTable.registerParameterName(name); + } ///< 注册函数参数名字,避免alloca重名 Value* getVariable(const std::string &name) { return variableTable.getVariable(name); } ///< 根据名字name和当前作用域获取变量 diff --git a/src/midend/IR.cpp b/src/midend/IR.cpp index 290b95a..d7a796a 100644 --- a/src/midend/IR.cpp +++ b/src/midend/IR.cpp @@ -1,6 +1,7 @@ #include "IR.h" #include #include +#include #include #include #include @@ -1033,12 +1034,23 @@ auto SymbolTable::addVariable(const std::string &name, Value *variable) -> Value if (curNode != nullptr) { std::stringstream ss; auto iter = variableIndex.find(name); + + // 处理超长变量名(超过100字符) + std::string displayName = name; + if (name.length() > 100) { + // 计算简单哈希 + std::hash hasher; + size_t hash = hasher(name); + // 截断到前100个字符 + 哈希后缀 + displayName = name.substr(0, 100) + "_hash_" + std::to_string(hash); + } + if (iter != variableIndex.end()) { - ss << name << iter->second ; + ss << displayName << iter->second ; iter->second += 1; } else { variableIndex.emplace(name, 1); - ss << name << 0 ; + ss << displayName << 0 ; } variable->setName(ss.str()); @@ -1056,6 +1068,47 @@ auto SymbolTable::addVariable(const std::string &name, Value *variable) -> Value return result; } + +/** + * 注册函数参数名字到符号表,确保后续的alloca变量不会使用相同的名字 + */ +void SymbolTable::registerParameterName(const std::string &name) { + if (curNode != nullptr) { + // 为当前函数作用域创建一个唯一的参数名标识 + std::string scopedName = name + "_param_" + std::to_string(reinterpret_cast(curNode)); + auto iter = variableIndex.find(scopedName); + if (iter != variableIndex.end()) { + iter->second += 1; + } else { + // 注册带作用域的参数名,确保在本作用域中后续的addVariable会避免冲突 + variableIndex.emplace(scopedName, 1); + } + // 同时确保原名字也有一个索引,这样addVariable会为alloca生成不同的名字 + auto iter2 = variableIndex.find(name); + if (iter2 == variableIndex.end()) { + variableIndex.emplace(name, 1); // 设置为1,这样addVariable会生成name1而不是name0 + } else { + iter2->second += 1; + } + } +} + +/** + * 直接添加变量到当前作用域,不进行重命名 + */ +void SymbolTable::addVariableDirectly(const std::string &name, Value *variable) { + if (curNode != nullptr) { + curNode->varList.emplace(name, variable); + auto global = dynamic_cast(variable); + auto constvar = dynamic_cast(variable); + if (global != nullptr) { + globals.emplace_back(global); + } else if (constvar != nullptr) { + globalconsts.emplace_back(constvar); + } + } +} + /** * 获取全局变量 */ diff --git a/src/midend/SysYIRGenerator.cpp b/src/midend/SysYIRGenerator.cpp index a31aae9..03e80e6 100644 --- a/src/midend/SysYIRGenerator.cpp +++ b/src/midend/SysYIRGenerator.cpp @@ -1210,15 +1210,25 @@ std::any SysYIRGenerator::visitFuncDef(SysYParser::FuncDefContext *ctx){ for(int i = 0; i < paramActualTypes.size(); ++i) { Argument* arg = new Argument(paramActualTypes[i], function, i, paramNames[i]); function->insertArgument(arg); + } + // 先将所有参数名字注册到符号表中,确保alloca不会使用相同的名字 + for (int i = 0; i < paramNames.size(); ++i) { + // 预先注册参数名字,这样addVariable就会使用不同的后缀 + module->registerParameterName(paramNames[i]); } auto funcArgs = function->getArguments(); std::vector allocas; for (int i = 0; i < paramActualTypes.size(); ++i) { - AllocaInst *alloca = builder.createAllocaInst(Type::getPointerType(paramActualTypes[i]), paramNames[i]); + // 使用函数特定的前缀来确保参数alloca名字唯一 + std::string allocaName = name + "_param_" + paramNames[i]; + AllocaInst *alloca = builder.createAllocaInst(Type::getPointerType(paramActualTypes[i]), allocaName); + // 直接设置唯一名字,不依赖addVariable的命名逻辑 + alloca->setName(allocaName); allocas.push_back(alloca); - module->addVariable(paramNames[i], alloca); + // 直接添加到符号表,使用原参数名作为查找键 + module->addVariableDirectly(paramNames[i], alloca); } for(int i = 0; i < paramActualTypes.size(); ++i) {