Merge branch 'midend' into backend

This commit is contained in:
Lixuanwang
2025-08-04 16:48:30 +08:00
2 changed files with 338 additions and 117 deletions

View File

@ -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<Value *> 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<GEPKey, Value*> availableGEPs; ///< 用于存储 GEP 的缓存
std::map<ExpKey, Value*> availableBinaryExpressions;
std::map<UnExpKey, Value*> availableUnaryExpressions;
std::map<Value*, Value*> 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<Value*>& indices);

View File

@ -38,6 +38,116 @@ std::pair<long long, int> 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<ExpKey> binaryKeysToRemove;
for (const auto &pair : availableBinaryExpressions) {
// 检查左操作数
// 如果左操作数是 LoadInst并且它从 storedAddress 加载
if (auto loadInst = dynamic_cast<LoadInst *>(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<LoadInst *>(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<UnExpKey> unaryKeysToRemove;
for (const auto &pair : availableUnaryExpressions) {
// 检查操作数
if (auto loadInst = dynamic_cast<LoadInst *>(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<GEPKey> gepKeysToRemove;
for (const auto &pair : availableGEPs) {
// 检查 GEP 的基指针是否受存储影响
if (auto loadInst = dynamic_cast<LoadInst *>(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<LoadInst *>(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<Value*> BinaryValueStack; ///< 用于存储value的栈
// std::vector<int> 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<ConstantInteger *>(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<BinaryOp>(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<ConstantInteger *>(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<BinaryOp>(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<ArrayValueTree *>(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<Type *> paramActualTypes;
@ -1143,7 +1296,16 @@ std::any SysYIRGenerator::visitAssignStmt(SysYParser::AssignStmtContext *ctx) {
if (AllocaInst *alloc = dynamic_cast<AllocaInst *>(variable)) {
Type* allocatedType = alloc->getType()->as<PointerType>()->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<SysYParser::BlockStmtContext *>(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<SysYParser::BlockStmtContext *>(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<SysYParser::BlockStmtContext *>(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<AllocaInst*>(variable) || dynamic_cast<GlobalValue*>(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<Value*>(nullptr);
}
} else {
// 访问数组元素或子数组(有索引,或变量本身是数组/多维指针)
Value* gepBasePointer = nullptr;
std::vector<Value*> gepIndices; // 准备传递给 getGEPAddressInst 的索引列表
// GEP 的基指针就是变量本身(它是一个指向内存的指针)
std::vector<Value*> gepIndices;
if (AllocaInst *alloc = dynamic_cast<AllocaInst *>(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<PointerType>()->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<GlobalValue *>(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<ConstantVariable *>(variable)) {
// 情况 C: 常量变量 (ConstantVariable),如果它代表全局数组常量
// 假设 ConstantVariable 可以直接作为 GEP 的基指针。
gepBasePointer = constV;
// 对于常量数组,也需要 0 索引来“步过”整个数组。
// 这里可以进一步检查 constV->getType()->as<PointerType>()->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<Value *>(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<Value *>(visitCall(ctx->call())));BinaryExpLenStack.back()++;
invalidateExpressionsOnCall();
} else if (ctx->unaryOp() != nullptr) {
// 遇到一元操作符,将其压入 BinaryExpStack
auto opNode = dynamic_cast<antlr4::tree::TerminalNode*>(ctx->unaryOp()->children[0]);