diff --git a/src/include/midend/SysYIRGenerator.h b/src/include/midend/SysYIRGenerator.h index bd671ee..b4d4e57 100644 --- a/src/include/midend/SysYIRGenerator.h +++ b/src/include/midend/SysYIRGenerator.h @@ -86,7 +86,60 @@ private: case LPAREN: case RPAREN: return 0; // Parentheses have lowest precedence for stack logic default: return -1; // Unknown operator } - } + }; + + struct ExpKey { + BinaryOp op; ///< 操作符 + Value *left; ///< 左操作数 + Value *right; ///< 右操作数 + ExpKey(BinaryOp op, Value *left, Value *right) : op(op), left(left), right(right) {} + + bool operator<(const ExpKey &other) const { + if (op != other.op) + return op < other.op; ///< 比较操作符 + if (left != other.left) + return left < other.left; ///< 比较左操作 + return right < other.right; ///< 比较右操作数 + } ///< 重载小于运算符用于比较ExpKey + }; + + struct UnExpKey { + BinaryOp op; ///< 一元操作符 + Value *operand; ///< 操作数 + UnExpKey(BinaryOp op, Value *operand) : op(op), operand(operand) {} + + bool operator<(const UnExpKey &other) const { + if (op != other.op) + return op < other.op; ///< 比较操作符 + return operand < other.operand; ///< 比较操作数 + } ///< 重载小于运算符用于比较UnExpKey + }; + + struct GEPKey { + Value *basePointer; + std::vector indices; + + // 为 std::map 定义比较运算符,使得 GEPKey 可以作为键 + bool operator<(const GEPKey &other) const { + if (basePointer != other.basePointer) { + return basePointer < other.basePointer; + } + // 逐个比较索引,确保顺序一致 + if (indices.size() != other.indices.size()) { + return indices.size() < other.indices.size(); + } + for (size_t i = 0; i < indices.size(); ++i) { + if (indices[i] != other.indices[i]) { + return indices[i] < other.indices[i]; + } + } + return false; // 如果 basePointer 和所有索引都相同,则认为相等 + } + }; + std::map availableGEPs; ///< 用于存储 GEP 的缓存 + std::map availableBinaryExpressions; + std::map availableUnaryExpressions; + std::map availableLoads; public: SysYIRGenerator() = default; @@ -167,6 +220,15 @@ public: Value* computeExp(SysYParser::ExpContext *ctx, Type* targetType = nullptr); Value* computeAddExp(SysYParser::AddExpContext *ctx, Type* targetType = nullptr); void compute(); + + // 参数是发生 store 操作的目标地址/变量的 Value* + void invalidateExpressionsOnStore(Value* storedAddress); + + // 清除因函数调用而失效的表达式缓存(保守策略) + void invalidateExpressionsOnCall(); + + // 在进入新的基本块时清空所有表达式缓存 + void enterNewBasicBlock(); public: // 获取GEP指令的地址 Value* getGEPAddressInst(Value* basePointer, const std::vector& indices); diff --git a/src/midend/SysYIRGenerator.cpp b/src/midend/SysYIRGenerator.cpp index b0ffab5..2e0e910 100644 --- a/src/midend/SysYIRGenerator.cpp +++ b/src/midend/SysYIRGenerator.cpp @@ -38,6 +38,116 @@ std::pair calculate_signed_magic(int d) { return {m, k}; } +// 清除因函数调用而失效的表达式缓存(保守策略) +void SysYIRGenerator::invalidateExpressionsOnCall() { + availableBinaryExpressions.clear(); + availableUnaryExpressions.clear(); + availableLoads.clear(); + availableGEPs.clear(); +} + +// 在进入新的基本块时清空所有表达式缓存 +void SysYIRGenerator::enterNewBasicBlock() { + availableBinaryExpressions.clear(); + availableUnaryExpressions.clear(); + availableLoads.clear(); + availableGEPs.clear(); +} + +// 清除因变量赋值而失效的表达式缓存 +// @param storedAddress: store 指令的目标地址 (例如 AllocaInst* 或 GEPInst*) +void SysYIRGenerator::invalidateExpressionsOnStore(Value *storedAddress) { + // 遍历二元表达式缓存,移除受影响的条目 + // 创建一个临时列表来存储要移除的键,避免在迭代时修改容器 + std::vector binaryKeysToRemove; + for (const auto &pair : availableBinaryExpressions) { + // 检查左操作数 + // 如果左操作数是 LoadInst,并且它从 storedAddress 加载 + if (auto loadInst = dynamic_cast(pair.first.left)) { + if (loadInst->getPointer() == storedAddress) { + binaryKeysToRemove.push_back(pair.first); + continue; // 这个表达式已标记为移除,跳到下一个 + } + } + // 如果左操作数本身就是被存储的地址 (例如,将一个地址值直接作为操作数,虽然不常见) + if (pair.first.left == storedAddress) { + binaryKeysToRemove.push_back(pair.first); + continue; + } + + // 检查右操作数,逻辑同左操作数 + if (auto loadInst = dynamic_cast(pair.first.right)) { + if (loadInst->getPointer() == storedAddress) { + binaryKeysToRemove.push_back(pair.first); + continue; + } + } + if (pair.first.right == storedAddress) { + binaryKeysToRemove.push_back(pair.first); + continue; + } + } + // 实际移除条目 + for (const auto &key : binaryKeysToRemove) { + availableBinaryExpressions.erase(key); + } + + // 遍历一元表达式缓存,移除受影响的条目 + std::vector unaryKeysToRemove; + for (const auto &pair : availableUnaryExpressions) { + // 检查操作数 + if (auto loadInst = dynamic_cast(pair.first.operand)) { + if (loadInst->getPointer() == storedAddress) { + unaryKeysToRemove.push_back(pair.first); + continue; + } + } + if (pair.first.operand == storedAddress) { + unaryKeysToRemove.push_back(pair.first); + continue; + } + } + // 实际移除条目 + for (const auto &key : unaryKeysToRemove) { + availableUnaryExpressions.erase(key); + } + availableLoads.erase(storedAddress); + + std::vector gepKeysToRemove; + for (const auto &pair : availableGEPs) { + // 检查 GEP 的基指针是否受存储影响 + if (auto loadInst = dynamic_cast(pair.first.basePointer)) { + if (loadInst->getPointer() == storedAddress) { + gepKeysToRemove.push_back(pair.first); + continue; // 标记此GEP为移除,跳过后续检查 + } + } + // 如果基指针本身就是存储的目标地址 (不常见,但可能) + if (pair.first.basePointer == storedAddress) { + gepKeysToRemove.push_back(pair.first); + continue; + } + + // 检查 GEP 的每个索引是否受存储影响 + for (const auto &indexVal : pair.first.indices) { + if (auto loadInst = dynamic_cast(indexVal)) { + if (loadInst->getPointer() == storedAddress) { + gepKeysToRemove.push_back(pair.first); + break; // 标记此GEP为移除,并跳出内部循环 + } + } + // 如果索引本身就是存储的目标地址 + if (indexVal == storedAddress) { + gepKeysToRemove.push_back(pair.first); + break; + } + } + } + // 实际移除条目 + for (const auto &key : gepKeysToRemove) { + availableGEPs.erase(key); + } +} // std::vector BinaryValueStack; ///< 用于存储value的栈 // std::vector BinaryOpStack; ///< 用于存储二元表达式的操作符栈 @@ -267,46 +377,56 @@ void SysYIRGenerator::compute() { } } else { // 否则,创建相应的IR指令 - if (commonType == Type::getIntType()) { - switch (op) { - case BinaryOp::ADD: resultValue = builder.createAddInst(lhs, rhs); break; - case BinaryOp::SUB: resultValue = builder.createSubInst(lhs, rhs); break; - case BinaryOp::MUL: resultValue = builder.createMulInst(lhs, rhs); break; - case BinaryOp::DIV: { - ConstantInteger *rhsConst = dynamic_cast(rhs); - if (rhsConst) { - int divisor = rhsConst->getInt(); - if (divisor > 0 && (divisor & (divisor - 1)) == 0) { - int shift = 0; - int temp = divisor; - while (temp > 1) { - temp >>= 1; - shift++; + ExpKey currentExpKey(static_cast(op), lhs, rhs); + auto it = availableBinaryExpressions.find(currentExpKey); + + if (it != availableBinaryExpressions.end()) { + // 在缓存中找到,重用结果 + resultValue = it->second; + } else { + if (commonType == Type::getIntType()) { + switch (op) { + case BinaryOp::ADD: resultValue = builder.createAddInst(lhs, rhs); break; + case BinaryOp::SUB: resultValue = builder.createSubInst(lhs, rhs); break; + case BinaryOp::MUL: resultValue = builder.createMulInst(lhs, rhs); break; + case BinaryOp::DIV: { + ConstantInteger *rhsConst = dynamic_cast(rhs); + if (rhsConst) { + int divisor = rhsConst->getInt(); + if (divisor > 0 && (divisor & (divisor - 1)) == 0) { + int shift = 0; + int temp = divisor; + while (temp > 1) { + temp >>= 1; + shift++; + } + resultValue = builder.createSRAInst(lhs, ConstantInteger::get(shift)); + } else { + resultValue = builder.createDivInst(lhs, rhs); } - resultValue = builder.createSRAInst(lhs, ConstantInteger::get(shift)); } else { resultValue = builder.createDivInst(lhs, rhs); } - } else { - resultValue = builder.createDivInst(lhs, rhs); + break; } - break; - } - case BinaryOp::MOD: resultValue = builder.createRemInst(lhs, rhs); break; - } - } else if (commonType == Type::getFloatType()) { - switch (op) { - case BinaryOp::ADD: resultValue = builder.createFAddInst(lhs, rhs); break; - case BinaryOp::SUB: resultValue = builder.createFSubInst(lhs, rhs); break; - case BinaryOp::MUL: resultValue = builder.createFMulInst(lhs, rhs); break; - case BinaryOp::DIV: resultValue = builder.createFDivInst(lhs, rhs); break; - case BinaryOp::MOD: - std::cerr << "Error: Modulo operator not supported for float types." << std::endl; + case BinaryOp::MOD: resultValue = builder.createRemInst(lhs, rhs); break; + } + } else if (commonType == Type::getFloatType()) { + switch (op) { + case BinaryOp::ADD: resultValue = builder.createFAddInst(lhs, rhs); break; + case BinaryOp::SUB: resultValue = builder.createFSubInst(lhs, rhs); break; + case BinaryOp::MUL: resultValue = builder.createFMulInst(lhs, rhs); break; + case BinaryOp::DIV: resultValue = builder.createFDivInst(lhs, rhs); break; + case BinaryOp::MOD: + std::cerr << "Error: Modulo operator not supported for float types." << std::endl; + return; + } + } else { + std::cerr << "Error: Unsupported type for binary instruction." << std::endl; return; } - } else { - std::cerr << "Error: Unsupported type for binary instruction." << std::endl; - return; + // 将新创建的指令结果添加到缓存 + availableBinaryExpressions[currentExpKey] = resultValue; } } break; @@ -358,36 +478,45 @@ void SysYIRGenerator::compute() { return; } } else { - // 否则,创建相应的IR指令 - switch (op) { - case BinaryOp::PLUS: - resultValue = operand; // 一元加指令通常直接返回操作数 - break; - case BinaryOp::NEG: { - if (commonType == sysy::Type::getIntType()) { - resultValue = builder.createNegInst(operand); - } else if (commonType == sysy::Type::getFloatType()) { - resultValue = builder.createFNegInst(operand); - } else { - std::cerr << "Error: Negation not supported for operand type." << std::endl; - return; + // 否则,创建相应的IR指令 (在这里应用CSE) + UnExpKey currentUnExpKey(static_cast(op), operand); + auto it = availableUnaryExpressions.find(currentUnExpKey); + if (it != availableUnaryExpressions.end()) { + // 在缓存中找到,重用结果 + resultValue = it->second; + } else { + switch (op) { + case BinaryOp::PLUS: + resultValue = operand; // 一元加指令通常直接返回操作数 + break; + case BinaryOp::NEG: { + if (commonType == sysy::Type::getIntType()) { + resultValue = builder.createNegInst(operand); + } else if (commonType == sysy::Type::getFloatType()) { + resultValue = builder.createFNegInst(operand); + } else { + std::cerr << "Error: Negation not supported for operand type." << std::endl; + return; + } + break; + } + case BinaryOp::NOT: + // 逻辑非 + if (commonType == sysy::Type::getIntType()) { + resultValue = builder.createNotInst(operand); + } else if (commonType == sysy::Type::getFloatType()) { + resultValue = builder.createFNotInst(operand); + } else { + std::cerr << "Error: Logical NOT not supported for operand type." << std::endl; + return; + } + break; + default: + std::cerr << "Error: Unknown unary operator for instructions: " << op << std::endl; + return; } - break; - } - case BinaryOp::NOT: - // 逻辑非 - if (commonType == sysy::Type::getIntType()) { - resultValue = builder.createNotInst(operand); - } else if (commonType == sysy::Type::getFloatType()) { - resultValue = builder.createFNotInst(operand); - } else { - std::cerr << "Error: Logical NOT not supported for operand type." << std::endl; - return; - } - break; - default: - std::cerr << "Error: Unknown unary operator for instructions: " << op << std::endl; - return; + // 将新创建的指令结果添加到缓存 + availableUnaryExpressions[currentUnExpKey] = resultValue; } } break; @@ -529,7 +658,19 @@ Value* SysYIRGenerator::getGEPAddressInst(Value* basePointer, const std::vector< // `indices` 向量现在由调用方(如 visitLValue, visitVarDecl, visitAssignStmt)负责完整准备, // 包括是否需要添加初始的 `0` 索引。 // 所以这里直接将其传递给 `builder.createGetElementPtrInst`。 - return builder.createGetElementPtrInst(basePointer, indices); + GEPKey key = {basePointer, indices}; + + // 尝试从缓存中查找 + auto it = availableGEPs.find(key); + if (it != availableGEPs.end()) { + return it->second; // 缓存命中,返回已有的 GEPInst* + } + + // 缓存未命中,创建新的 GEPInst + Value* gepInst = builder.createGetElementPtrInst(basePointer, indices); // 假设 builder 提供了 createGEPInst 方法 + availableGEPs[key] = gepInst; // 将新的 GEPInst* 加入缓存 + + return gepInst; } /* @@ -628,7 +769,13 @@ std::any SysYIRGenerator::visitConstDecl(SysYParser::ConstDeclContext *ctx) { // 显式地为局部常量在栈上分配空间 // alloca 的类型将是指针指向常量类型,例如 `int*` 或 `int[2][3]*` + // 将alloca全部集中到entry中 + auto entry = builder.getBasicBlock()->getParent()->getEntryBlock(); + auto it = builder.getPosition(); + auto nowblk = builder.getBasicBlock(); + builder.setPosition(entry, entry->terminator()); AllocaInst *alloca = builder.createAllocaInst(Type::getPointerType(variableType), name); + builder.setPosition(nowblk, it); ArrayValueTree *root = std::any_cast(constDef->constInitVal()->accept(this)); ValueCounter values; @@ -785,8 +932,12 @@ std::any SysYIRGenerator::visitVarDecl(SysYParser::VarDeclContext *ctx) { // 对于数组,alloca 的类型将是指针指向数组类型,例如 `int[2][3]*` // 对于标量,alloca 的类型将是指针指向标量类型,例如 `int*` - AllocaInst* alloca = - builder.createAllocaInst(Type::getPointerType(variableType), name); + auto entry = builder.getBasicBlock()->getParent()->getEntryBlock(); + auto it = builder.getPosition(); + auto nowblk = builder.getBasicBlock(); + builder.setPosition(entry, entry->terminator()); + AllocaInst *alloca = builder.createAllocaInst(Type::getPointerType(variableType), name); + builder.setPosition(nowblk, it); if (varDef->initVal() != nullptr) { ValueCounter values; @@ -988,6 +1139,8 @@ std::any SysYIRGenerator::visitFuncType(SysYParser::FuncTypeContext *ctx) { std::any SysYIRGenerator::visitFuncDef(SysYParser::FuncDefContext *ctx){ // 更新作用域 module->enterNewScope(); + // 清除CSE缓存 + enterNewBasicBlock(); auto name = ctx->Ident()->getText(); std::vector paramActualTypes; @@ -1143,7 +1296,16 @@ std::any SysYIRGenerator::visitAssignStmt(SysYParser::AssignStmtContext *ctx) { if (AllocaInst *alloc = dynamic_cast(variable)) { Type* allocatedType = alloc->getType()->as()->getBaseType(); if (allocatedType->isPointer()) { - gepBasePointer = builder.createLoadInst(alloc); + // 尝试从缓存中获取 builder.createLoadInst(alloc) 的结果 + auto it = availableLoads.find(alloc); + if (it != availableLoads.end()) { + gepBasePointer = it->second; // 缓存命中,重用 + } else { + gepBasePointer = builder.createLoadInst(alloc); // 缓存未命中,创建新的 LoadInst + availableLoads[alloc] = gepBasePointer; // 将结果加入缓存 + } + // --- CSE 结束 --- + // gepBasePointer = builder.createLoadInst(alloc); gepIndices = indices; } else { gepBasePointer = alloc; @@ -1205,9 +1367,9 @@ std::any SysYIRGenerator::visitAssignStmt(SysYParser::AssignStmtContext *ctx) { } } } - + builder.createStoreInst(RValue, LValue); - + invalidateExpressionsOnStore(LValue); return std::any(); } @@ -1244,7 +1406,9 @@ std::any SysYIRGenerator::visitIfStmt(SysYParser::IfStmtContext *ctx) { labelstring.str(""); function->addBasicBlock(thenBlock); builder.setPosition(thenBlock, thenBlock->end()); - + // CSE清除缓存 + enterNewBasicBlock(); + auto block = dynamic_cast(ctx->stmt(0)); // 如果是块语句,直接访问 // 否则访问语句 @@ -1263,7 +1427,9 @@ std::any SysYIRGenerator::visitIfStmt(SysYParser::IfStmtContext *ctx) { labelstring.str(""); function->addBasicBlock(elseBlock); builder.setPosition(elseBlock, elseBlock->end()); - + // CSE清除缓存 + enterNewBasicBlock(); + block = dynamic_cast(ctx->stmt(1)); if (block != nullptr) { visitBlockStmt(block); @@ -1280,7 +1446,9 @@ std::any SysYIRGenerator::visitIfStmt(SysYParser::IfStmtContext *ctx) { labelstring.str(""); function->addBasicBlock(exitBlock); builder.setPosition(exitBlock, exitBlock->end()); - + // CSE清除缓存 + enterNewBasicBlock(); + } else { builder.pushTrueBlock(thenBlock); builder.pushFalseBlock(exitBlock); @@ -1293,7 +1461,9 @@ std::any SysYIRGenerator::visitIfStmt(SysYParser::IfStmtContext *ctx) { labelstring.str(""); function->addBasicBlock(thenBlock); builder.setPosition(thenBlock, thenBlock->end()); - + // CSE清除缓存 + enterNewBasicBlock(); + auto block = dynamic_cast(ctx->stmt(0)); if (block != nullptr) { visitBlockStmt(block); @@ -1310,6 +1480,9 @@ std::any SysYIRGenerator::visitIfStmt(SysYParser::IfStmtContext *ctx) { labelstring.str(""); function->addBasicBlock(exitBlock); builder.setPosition(exitBlock, exitBlock->end()); + // CSE清除缓存 + enterNewBasicBlock(); + } return std::any(); } @@ -1327,7 +1500,9 @@ std::any SysYIRGenerator::visitWhileStmt(SysYParser::WhileStmtContext *ctx) { builder.createUncondBrInst(headBlock); BasicBlock::conectBlocks(curBlock, headBlock); builder.setPosition(headBlock, headBlock->end()); - + // CSE清除缓存 + enterNewBasicBlock(); + BasicBlock* bodyBlock = new BasicBlock(function); BasicBlock* exitBlock = new BasicBlock(function); @@ -1343,6 +1518,8 @@ std::any SysYIRGenerator::visitWhileStmt(SysYParser::WhileStmtContext *ctx) { labelstring.str(""); function->addBasicBlock(bodyBlock); builder.setPosition(bodyBlock, bodyBlock->end()); + // CSE清除缓存 + enterNewBasicBlock(); builder.pushBreakBlock(exitBlock); builder.pushContinueBlock(headBlock); @@ -1367,7 +1544,9 @@ std::any SysYIRGenerator::visitWhileStmt(SysYParser::WhileStmtContext *ctx) { labelstring.str(""); function->addBasicBlock(exitBlock); builder.setPosition(exitBlock, exitBlock->end()); - + // CSE清除缓存 + enterNewBasicBlock(); + return std::any(); } @@ -1482,62 +1661,34 @@ std::any SysYIRGenerator::visitLValue(SysYParser::LValueContext *ctx) { // 3. 处理可变变量 (AllocaInst/GlobalValue) 或带非常量索引的常量变量 // 这里区分标量访问和数组元素/子数组访问 - + Value *targetAddress = nullptr; // 检查是否是访问标量变量本身(没有索引,且声明维度为0) if (dims.empty() && declaredNumDims == 0) { - // 对于标量变量,直接加载其值。 - // variable 本身就是指向标量的指针 (e.g., int* %a) if (dynamic_cast(variable) || dynamic_cast(variable)) { - value = builder.createLoadInst(variable); + targetAddress = variable; } else { - // 如果走到这里且不是AllocaInst/GlobalValue,但dims为空且declaredNumDims为0, - // 且又不是ConstantVariable (前面已处理),则可能是错误情况。 assert(false && "Unhandled scalar variable type in LValue access."); return static_cast(nullptr); } } else { - // 访问数组元素或子数组(有索引,或变量本身是数组/多维指针) Value* gepBasePointer = nullptr; - std::vector gepIndices; // 准备传递给 getGEPAddressInst 的索引列表 - // GEP 的基指针就是变量本身(它是一个指向内存的指针) + std::vector gepIndices; if (AllocaInst *alloc = dynamic_cast(variable)) { - // 情况 A: 局部变量 (AllocaInst) - // 获取 AllocaInst 分配的内存的实际类型。 - // 例如:对于 `int b[10][20];`,`allocatedType` 是 `[10 x [20 x i32]]`。 - // 对于 `int b[][20]` 的函数参数,其 AllocaInst 存储的是一个指针, - // 此时 `allocatedType` 是 `[20 x i32]*`。 Type* allocatedType = alloc->getType()->as()->getBaseType(); - if (allocatedType->isPointer()) { - // 如果 AllocaInst 分配的是一个指针类型 (例如,用于存储函数参数的指针,如 int b[][20] 中的 b) - // 即 `allocatedType` 是一个指向数组指针的指针 (e.g., [20 x i32]**) - // 那么 GEP 的基指针是加载这个指针变量的值。 - gepBasePointer = builder.createLoadInst(alloc); // 加载出实际的指针值 (e.g., [20 x i32]*) - // 对于这种参数指针,用户提供的索引直接作用于它。不需要额外的 0。 + gepBasePointer = builder.createLoadInst(alloc); gepIndices = dims; } else { - // 如果 AllocaInst 分配的是实际的数组数据 (例如,int b[10][20] 中的 b) - // 那么 AllocaInst 本身就是 GEP 的基指针。 - // 这里的 `alloc` 是指向数组的指针 (e.g., [10 x [20 x i32]]*) - gepBasePointer = alloc; // 类型是 [10 x [20 x i32]]* - // 对于这种完整的数组分配,GEP 的第一个索引必须是 0,用于“步过”整个数组。 + gepBasePointer = alloc; gepIndices.push_back(ConstantInteger::get(0)); gepIndices.insert(gepIndices.end(), dims.begin(), dims.end()); } } else if (GlobalValue *glob = dynamic_cast(variable)) { - // 情况 B: 全局变量 (GlobalValue) - // GlobalValue 总是指向全局数据的指针。 - gepBasePointer = glob; // 类型是 [61 x [67 x i32]]* - // 对于全局数组,GEP 的第一个索引必须是 0,用于“步过”整个数组。 + gepBasePointer = glob; gepIndices.push_back(ConstantInteger::get(0)); gepIndices.insert(gepIndices.end(), dims.begin(), dims.end()); } else if (ConstantVariable *constV = dynamic_cast(variable)) { - // 情况 C: 常量变量 (ConstantVariable),如果它代表全局数组常量 - // 假设 ConstantVariable 可以直接作为 GEP 的基指针。 gepBasePointer = constV; - // 对于常量数组,也需要 0 索引来“步过”整个数组。 - // 这里可以进一步检查 constV->getType()->as()->getBaseType()->isArray() - // 但为了简洁,假设所有 ConstantVariable 作为 GEP 基指针时都需要此 0。 gepIndices.push_back(ConstantInteger::get(0)); gepIndices.insert(gepIndices.end(), dims.begin(), dims.end()); } else { @@ -1545,18 +1696,25 @@ std::any SysYIRGenerator::visitLValue(SysYParser::LValueContext *ctx) { return static_cast(nullptr); } - // 现在调用 getGEPAddressInst,传入正确准备的基指针和索引列表 - Value *targetAddress = getGEPAddressInst(gepBasePointer, gepIndices); + targetAddress = getGEPAddressInst(gepBasePointer, gepIndices); - // 如果提供的索引数量少于声明的维度数量,则表示访问的是子数组,返回其地址 - if (dims.size() < declaredNumDims) { - value = targetAddress; + } + + // 如果提供的索引数量少于声明的维度数量,则表示访问的是子数组,返回其地址 (无需加载) + if (dims.size() < declaredNumDims) { + value = targetAddress; + } else { + // value = builder.createLoadInst(targetAddress); + auto it = availableLoads.find(targetAddress); + if (it != availableLoads.end()) { + value = it->second; // 缓存命中,重用已有的 LoadInst 结果 } else { - // 否则,表示访问的是最终的标量元素,加载其值 - // 假设 createLoadInst 接受 Value* pointer - value = builder.createLoadInst(targetAddress); + // 缓存未命中,创建新的 LoadInst + value = builder.createLoadInst(targetAddress); + availableLoads[targetAddress] = value; // 将新的 LoadInst 结果加入缓存 } } + return value; } @@ -1676,6 +1834,7 @@ std::any SysYIRGenerator::visitUnaryExp(SysYParser::UnaryExpContext *ctx) { visitPrimaryExp(ctx->primaryExp()); } else if (ctx->call() != nullptr) { BinaryExpStack.push_back(std::any_cast(visitCall(ctx->call())));BinaryExpLenStack.back()++; + invalidateExpressionsOnCall(); } else if (ctx->unaryOp() != nullptr) { // 遇到一元操作符,将其压入 BinaryExpStack auto opNode = dynamic_cast(ctx->unaryOp()->children[0]);