From 2c5e4cead1f716474c99a83ca52e882a9e8d0b78 Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Sun, 10 Aug 2025 15:19:24 +0800 Subject: [PATCH] =?UTF-8?q?[midend-llvmirprint]=E4=BF=AE=E5=A4=8D=E9=83=A8?= =?UTF-8?q?=E5=88=86=E6=89=93=E5=8D=B0=E9=80=BB=E8=BE=91=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E7=94=9F=E6=88=90IR=E6=97=B6=E7=9A=84=E5=9F=BA?= =?UTF-8?q?=E6=9C=AC=E5=9D=97=E9=94=99=E8=AF=AF=E7=9A=84=E5=89=8D=E5=90=8E?= =?UTF-8?q?=E9=A9=B1=E5=85=B3=E7=B3=BB=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/midend/IR.cpp | 113 +++++++++++++++------------------ src/midend/SysYIRGenerator.cpp | 2 +- 2 files changed, 52 insertions(+), 63 deletions(-) diff --git a/src/midend/IR.cpp b/src/midend/IR.cpp index 0c105cf..c6a2ce5 100644 --- a/src/midend/IR.cpp +++ b/src/midend/IR.cpp @@ -13,10 +13,19 @@ using namespace std; inline std::string getMachineCode(float fval) { - uint32_t mrf = *reinterpret_cast(&fval); + // LLVM IR要求float也使用64位十六进制表示 + // 将float扩展为double精度格式 + double dval = static_cast(fval); + uint64_t bits = *reinterpret_cast(&dval); + + // 如果是0,直接返回 + if (bits == 0 || fval == 0.0f) { + return "0x0000000000000000"; + } + std::stringstream ss; - ss << std::hex << std::uppercase << std::setfill('0') << std::setw(8) << mrf; - return "0x" + ss.str(); + ss << "0x" << std::hex << std::uppercase << std::setfill('0') << std::setw(16) << bits; + return ss.str(); } /** @@ -638,7 +647,7 @@ void PhiInst::print(std::ostream &os) const { } os << " ["; printOperand(os, getIncomingValue(i)); - os << ", "; + os << ", %"; printBlockName(os, getIncomingBlock(i)); os << "]"; } @@ -723,27 +732,34 @@ void AllocaInst::print(std::ostream &os) const { } void BinaryInst::print(std::ostream &os) const { - printVarName(os, this) << " = "; - auto kind = getKind(); // 检查是否为比较指令 if (kind == kICmpEQ || kind == kICmpNE || kind == kICmpLT || kind == kICmpGT || kind == kICmpLE || kind == kICmpGE) { - // 整数比较指令 - os << getKindString() << " " << *getLhs()->getType() << " "; + // 整数比较指令 - 生成临时i1结果然后转换为i32 + static int tmpCmpCounter = 0; + std::string tmpName = "tmp_icmp_" + std::to_string(++tmpCmpCounter); + os << "%" << tmpName << " = " << getKindString() << " " << *getLhs()->getType() << " "; printOperand(os, getLhs()); os << ", "; printOperand(os, getRhs()); + os << "\n "; + printVarName(os, this) << " = zext i1 %" << tmpName << " to i32"; } else if (kind == kFCmpEQ || kind == kFCmpNE || kind == kFCmpLT || kind == kFCmpGT || kind == kFCmpLE || kind == kFCmpGE) { - // 浮点比较指令 - os << getKindString() << " " << *getLhs()->getType() << " "; + // 浮点比较指令 - 生成临时i1结果然后转换为i32 + static int tmpCmpCounter = 0; + std::string tmpName = "tmp_fcmp_" + std::to_string(++tmpCmpCounter); + os << "%" << tmpName << " = " << getKindString() << " " << *getLhs()->getType() << " "; printOperand(os, getLhs()); os << ", "; printOperand(os, getRhs()); + os << "\n "; + printVarName(os, this) << " = zext i1 %" << tmpName << " to i32"; } else { // 算术和逻辑指令 + printVarName(os, this) << " = "; os << getKindString() << " " << *getType() << " "; printOperand(os, getLhs()); os << ", "; @@ -769,38 +785,15 @@ void UncondBrInst::print(std::ostream &os) const { void CondBrInst::print(std::ostream &os) const { Value* condition = getCondition(); - // 检查条件是否来自比较指令 - if (auto* binaryInst = dynamic_cast(condition)) { - auto kind = binaryInst->getKind(); - if (kind == kICmpEQ || kind == kICmpNE || kind == kICmpLT || - kind == kICmpGT || kind == kICmpLE || kind == kICmpGE || - kind == kFCmpEQ || kind == kFCmpNE || kind == kFCmpLT || - kind == kFCmpGT || kind == kFCmpLE || kind == kFCmpGE) { - // 比较指令返回i1类型,直接使用 - os << "br i1 "; - printOperand(os, condition); - } else { - // 其他指令返回i32,需要转换 - static int tmpCondCounter = 0; - std::string condName = condition->getName(); - if (condName.empty()) { - condName = "const" + std::to_string(++tmpCondCounter); - } - os << "%tmp_cond_" << condName << " = icmp ne i32 "; - printOperand(os, condition); - os << ", 0\n br i1 %tmp_cond_" << condName; - } - } else { - // 对于非BinaryInst的条件(如变量),假设是i32需要转换 - static int tmpCondCounter = 0; - std::string condName = condition->getName(); - if (condName.empty()) { - condName = "const" + std::to_string(++tmpCondCounter); - } - os << "%tmp_cond_" << condName << " = icmp ne i32 "; - printOperand(os, condition); - os << ", 0\n br i1 %tmp_cond_" << condName; + // 由于所有条件都是i32类型(包括比较结果),统一转换为i1 + static int tmpCondCounter = 0; + std::string condName = condition->getName(); + if (condName.empty()) { + condName = "const" + std::to_string(++tmpCondCounter); } + os << "%tmp_cond_" << condName << " = icmp ne i32 "; + printOperand(os, condition); + os << ", 0\n br i1 %tmp_cond_" << condName; os << ", label %"; printBlockName(os, getThenBlock()); @@ -1079,14 +1072,26 @@ auto SymbolTable::addVariable(const std::string &name, Value *variable) -> Value displayName = name.substr(0, 100) + "_hash_" + std::to_string(hash); } + // 区分全局变量和局部变量的命名 + bool isGlobalVariable = (dynamic_cast(variable) != nullptr) || + (dynamic_cast(variable) != nullptr); + + int index = 0; if (iter != variableIndex.end()) { - ss << displayName << iter->second ; + index = iter->second; iter->second += 1; } else { variableIndex.emplace(name, 1); - ss << displayName << 0 ; } - + + if (isGlobalVariable) { + // 全局变量不使用 local_ 前缀 + ss << displayName << index; + } else { + // 局部变量使用 "local_" 前缀确保不会和函数参数名冲突 + ss << "local_" << displayName << index; + } + variable->setName(ss.str()); curNode->varList.emplace(name, variable); auto global = dynamic_cast(variable); @@ -1107,24 +1112,8 @@ auto SymbolTable::addVariable(const std::string &name, Value *variable) -> Value * 注册函数参数名字到符号表,确保后续的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; - } - } + // 由于局部变量现在使用 "local_" 前缀,不需要复杂的冲突避免逻辑 + // 这个方法现在主要用于参数相关的记录,可以简化 } /** diff --git a/src/midend/SysYIRGenerator.cpp b/src/midend/SysYIRGenerator.cpp index 03e80e6..a0cd6af 100644 --- a/src/midend/SysYIRGenerator.cpp +++ b/src/midend/SysYIRGenerator.cpp @@ -1546,7 +1546,7 @@ std::any SysYIRGenerator::visitWhileStmt(SysYParser::WhileStmtContext *ctx) { } builder.createUncondBrInst(headBlock); - BasicBlock::conectBlocks(builder.getBasicBlock(), exitBlock); + BasicBlock::conectBlocks(builder.getBasicBlock(), headBlock); builder.popBreakBlock(); builder.popContinueBlock();