Merge branch 'midend' into backend
This commit is contained in:
@@ -86,7 +86,60 @@ private:
|
|||||||
case LPAREN: case RPAREN: return 0; // Parentheses have lowest precedence for stack logic
|
case LPAREN: case RPAREN: return 0; // Parentheses have lowest precedence for stack logic
|
||||||
default: return -1; // Unknown operator
|
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:
|
public:
|
||||||
SysYIRGenerator() = default;
|
SysYIRGenerator() = default;
|
||||||
@@ -167,6 +220,15 @@ public:
|
|||||||
Value* computeExp(SysYParser::ExpContext *ctx, Type* targetType = nullptr);
|
Value* computeExp(SysYParser::ExpContext *ctx, Type* targetType = nullptr);
|
||||||
Value* computeAddExp(SysYParser::AddExpContext *ctx, Type* targetType = nullptr);
|
Value* computeAddExp(SysYParser::AddExpContext *ctx, Type* targetType = nullptr);
|
||||||
void compute();
|
void compute();
|
||||||
|
|
||||||
|
// 参数是发生 store 操作的目标地址/变量的 Value*
|
||||||
|
void invalidateExpressionsOnStore(Value* storedAddress);
|
||||||
|
|
||||||
|
// 清除因函数调用而失效的表达式缓存(保守策略)
|
||||||
|
void invalidateExpressionsOnCall();
|
||||||
|
|
||||||
|
// 在进入新的基本块时清空所有表达式缓存
|
||||||
|
void enterNewBasicBlock();
|
||||||
public:
|
public:
|
||||||
// 获取GEP指令的地址
|
// 获取GEP指令的地址
|
||||||
Value* getGEPAddressInst(Value* basePointer, const std::vector<Value*>& indices);
|
Value* getGEPAddressInst(Value* basePointer, const std::vector<Value*>& indices);
|
||||||
|
|||||||
@@ -38,6 +38,116 @@ std::pair<long long, int> calculate_signed_magic(int d) {
|
|||||||
return {m, k};
|
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<Value*> BinaryValueStack; ///< 用于存储value的栈
|
||||||
// std::vector<int> BinaryOpStack; ///< 用于存储二元表达式的操作符栈
|
// std::vector<int> BinaryOpStack; ///< 用于存储二元表达式的操作符栈
|
||||||
@@ -267,46 +377,56 @@ void SysYIRGenerator::compute() {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 否则,创建相应的IR指令
|
// 否则,创建相应的IR指令
|
||||||
if (commonType == Type::getIntType()) {
|
ExpKey currentExpKey(static_cast<BinaryOp>(op), lhs, rhs);
|
||||||
switch (op) {
|
auto it = availableBinaryExpressions.find(currentExpKey);
|
||||||
case BinaryOp::ADD: resultValue = builder.createAddInst(lhs, rhs); break;
|
|
||||||
case BinaryOp::SUB: resultValue = builder.createSubInst(lhs, rhs); break;
|
if (it != availableBinaryExpressions.end()) {
|
||||||
case BinaryOp::MUL: resultValue = builder.createMulInst(lhs, rhs); break;
|
// 在缓存中找到,重用结果
|
||||||
case BinaryOp::DIV: {
|
resultValue = it->second;
|
||||||
ConstantInteger *rhsConst = dynamic_cast<ConstantInteger *>(rhs);
|
} else {
|
||||||
if (rhsConst) {
|
if (commonType == Type::getIntType()) {
|
||||||
int divisor = rhsConst->getInt();
|
switch (op) {
|
||||||
if (divisor > 0 && (divisor & (divisor - 1)) == 0) {
|
case BinaryOp::ADD: resultValue = builder.createAddInst(lhs, rhs); break;
|
||||||
int shift = 0;
|
case BinaryOp::SUB: resultValue = builder.createSubInst(lhs, rhs); break;
|
||||||
int temp = divisor;
|
case BinaryOp::MUL: resultValue = builder.createMulInst(lhs, rhs); break;
|
||||||
while (temp > 1) {
|
case BinaryOp::DIV: {
|
||||||
temp >>= 1;
|
ConstantInteger *rhsConst = dynamic_cast<ConstantInteger *>(rhs);
|
||||||
shift++;
|
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 {
|
} else {
|
||||||
resultValue = builder.createDivInst(lhs, rhs);
|
resultValue = builder.createDivInst(lhs, rhs);
|
||||||
}
|
}
|
||||||
} else {
|
break;
|
||||||
resultValue = builder.createDivInst(lhs, rhs);
|
|
||||||
}
|
}
|
||||||
break;
|
case BinaryOp::MOD: resultValue = builder.createRemInst(lhs, rhs); break;
|
||||||
}
|
}
|
||||||
case BinaryOp::MOD: resultValue = builder.createRemInst(lhs, rhs); break;
|
} else if (commonType == Type::getFloatType()) {
|
||||||
}
|
switch (op) {
|
||||||
} else if (commonType == Type::getFloatType()) {
|
case BinaryOp::ADD: resultValue = builder.createFAddInst(lhs, rhs); break;
|
||||||
switch (op) {
|
case BinaryOp::SUB: resultValue = builder.createFSubInst(lhs, rhs); break;
|
||||||
case BinaryOp::ADD: resultValue = builder.createFAddInst(lhs, rhs); break;
|
case BinaryOp::MUL: resultValue = builder.createFMulInst(lhs, rhs); break;
|
||||||
case BinaryOp::SUB: resultValue = builder.createFSubInst(lhs, rhs); break;
|
case BinaryOp::DIV: resultValue = builder.createFDivInst(lhs, rhs); break;
|
||||||
case BinaryOp::MUL: resultValue = builder.createFMulInst(lhs, rhs); break;
|
case BinaryOp::MOD:
|
||||||
case BinaryOp::DIV: resultValue = builder.createFDivInst(lhs, rhs); break;
|
std::cerr << "Error: Modulo operator not supported for float types." << std::endl;
|
||||||
case BinaryOp::MOD:
|
return;
|
||||||
std::cerr << "Error: Modulo operator not supported for float types." << std::endl;
|
}
|
||||||
|
} else {
|
||||||
|
std::cerr << "Error: Unsupported type for binary instruction." << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
// 将新创建的指令结果添加到缓存
|
||||||
std::cerr << "Error: Unsupported type for binary instruction." << std::endl;
|
availableBinaryExpressions[currentExpKey] = resultValue;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -358,36 +478,45 @@ void SysYIRGenerator::compute() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 否则,创建相应的IR指令
|
// 否则,创建相应的IR指令 (在这里应用CSE)
|
||||||
switch (op) {
|
UnExpKey currentUnExpKey(static_cast<BinaryOp>(op), operand);
|
||||||
case BinaryOp::PLUS:
|
auto it = availableUnaryExpressions.find(currentUnExpKey);
|
||||||
resultValue = operand; // 一元加指令通常直接返回操作数
|
if (it != availableUnaryExpressions.end()) {
|
||||||
break;
|
// 在缓存中找到,重用结果
|
||||||
case BinaryOp::NEG: {
|
resultValue = it->second;
|
||||||
if (commonType == sysy::Type::getIntType()) {
|
} else {
|
||||||
resultValue = builder.createNegInst(operand);
|
switch (op) {
|
||||||
} else if (commonType == sysy::Type::getFloatType()) {
|
case BinaryOp::PLUS:
|
||||||
resultValue = builder.createFNegInst(operand);
|
resultValue = operand; // 一元加指令通常直接返回操作数
|
||||||
} else {
|
break;
|
||||||
std::cerr << "Error: Negation not supported for operand type." << std::endl;
|
case BinaryOp::NEG: {
|
||||||
return;
|
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;
|
// 将新创建的指令结果添加到缓存
|
||||||
}
|
availableUnaryExpressions[currentUnExpKey] = resultValue;
|
||||||
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;
|
break;
|
||||||
@@ -529,7 +658,19 @@ Value* SysYIRGenerator::getGEPAddressInst(Value* basePointer, const std::vector<
|
|||||||
// `indices` 向量现在由调用方(如 visitLValue, visitVarDecl, visitAssignStmt)负责完整准备,
|
// `indices` 向量现在由调用方(如 visitLValue, visitVarDecl, visitAssignStmt)负责完整准备,
|
||||||
// 包括是否需要添加初始的 `0` 索引。
|
// 包括是否需要添加初始的 `0` 索引。
|
||||||
// 所以这里直接将其传递给 `builder.createGetElementPtrInst`。
|
// 所以这里直接将其传递给 `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 的类型将是指针指向常量类型,例如 `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);
|
AllocaInst *alloca = builder.createAllocaInst(Type::getPointerType(variableType), name);
|
||||||
|
builder.setPosition(nowblk, it);
|
||||||
|
|
||||||
ArrayValueTree *root = std::any_cast<ArrayValueTree *>(constDef->constInitVal()->accept(this));
|
ArrayValueTree *root = std::any_cast<ArrayValueTree *>(constDef->constInitVal()->accept(this));
|
||||||
ValueCounter values;
|
ValueCounter values;
|
||||||
@@ -785,8 +932,12 @@ std::any SysYIRGenerator::visitVarDecl(SysYParser::VarDeclContext *ctx) {
|
|||||||
|
|
||||||
// 对于数组,alloca 的类型将是指针指向数组类型,例如 `int[2][3]*`
|
// 对于数组,alloca 的类型将是指针指向数组类型,例如 `int[2][3]*`
|
||||||
// 对于标量,alloca 的类型将是指针指向标量类型,例如 `int*`
|
// 对于标量,alloca 的类型将是指针指向标量类型,例如 `int*`
|
||||||
AllocaInst* alloca =
|
auto entry = builder.getBasicBlock()->getParent()->getEntryBlock();
|
||||||
builder.createAllocaInst(Type::getPointerType(variableType), name);
|
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) {
|
if (varDef->initVal() != nullptr) {
|
||||||
ValueCounter values;
|
ValueCounter values;
|
||||||
@@ -988,6 +1139,8 @@ std::any SysYIRGenerator::visitFuncType(SysYParser::FuncTypeContext *ctx) {
|
|||||||
std::any SysYIRGenerator::visitFuncDef(SysYParser::FuncDefContext *ctx){
|
std::any SysYIRGenerator::visitFuncDef(SysYParser::FuncDefContext *ctx){
|
||||||
// 更新作用域
|
// 更新作用域
|
||||||
module->enterNewScope();
|
module->enterNewScope();
|
||||||
|
// 清除CSE缓存
|
||||||
|
enterNewBasicBlock();
|
||||||
|
|
||||||
auto name = ctx->Ident()->getText();
|
auto name = ctx->Ident()->getText();
|
||||||
std::vector<Type *> paramActualTypes;
|
std::vector<Type *> paramActualTypes;
|
||||||
@@ -1143,7 +1296,16 @@ std::any SysYIRGenerator::visitAssignStmt(SysYParser::AssignStmtContext *ctx) {
|
|||||||
if (AllocaInst *alloc = dynamic_cast<AllocaInst *>(variable)) {
|
if (AllocaInst *alloc = dynamic_cast<AllocaInst *>(variable)) {
|
||||||
Type* allocatedType = alloc->getType()->as<PointerType>()->getBaseType();
|
Type* allocatedType = alloc->getType()->as<PointerType>()->getBaseType();
|
||||||
if (allocatedType->isPointer()) {
|
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;
|
gepIndices = indices;
|
||||||
} else {
|
} else {
|
||||||
gepBasePointer = alloc;
|
gepBasePointer = alloc;
|
||||||
@@ -1205,9 +1367,9 @@ std::any SysYIRGenerator::visitAssignStmt(SysYParser::AssignStmtContext *ctx) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.createStoreInst(RValue, LValue);
|
builder.createStoreInst(RValue, LValue);
|
||||||
|
invalidateExpressionsOnStore(LValue);
|
||||||
return std::any();
|
return std::any();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1244,7 +1406,9 @@ std::any SysYIRGenerator::visitIfStmt(SysYParser::IfStmtContext *ctx) {
|
|||||||
labelstring.str("");
|
labelstring.str("");
|
||||||
function->addBasicBlock(thenBlock);
|
function->addBasicBlock(thenBlock);
|
||||||
builder.setPosition(thenBlock, thenBlock->end());
|
builder.setPosition(thenBlock, thenBlock->end());
|
||||||
|
// CSE清除缓存
|
||||||
|
enterNewBasicBlock();
|
||||||
|
|
||||||
auto block = dynamic_cast<SysYParser::BlockStmtContext *>(ctx->stmt(0));
|
auto block = dynamic_cast<SysYParser::BlockStmtContext *>(ctx->stmt(0));
|
||||||
// 如果是块语句,直接访问
|
// 如果是块语句,直接访问
|
||||||
// 否则访问语句
|
// 否则访问语句
|
||||||
@@ -1263,7 +1427,9 @@ std::any SysYIRGenerator::visitIfStmt(SysYParser::IfStmtContext *ctx) {
|
|||||||
labelstring.str("");
|
labelstring.str("");
|
||||||
function->addBasicBlock(elseBlock);
|
function->addBasicBlock(elseBlock);
|
||||||
builder.setPosition(elseBlock, elseBlock->end());
|
builder.setPosition(elseBlock, elseBlock->end());
|
||||||
|
// CSE清除缓存
|
||||||
|
enterNewBasicBlock();
|
||||||
|
|
||||||
block = dynamic_cast<SysYParser::BlockStmtContext *>(ctx->stmt(1));
|
block = dynamic_cast<SysYParser::BlockStmtContext *>(ctx->stmt(1));
|
||||||
if (block != nullptr) {
|
if (block != nullptr) {
|
||||||
visitBlockStmt(block);
|
visitBlockStmt(block);
|
||||||
@@ -1280,7 +1446,9 @@ std::any SysYIRGenerator::visitIfStmt(SysYParser::IfStmtContext *ctx) {
|
|||||||
labelstring.str("");
|
labelstring.str("");
|
||||||
function->addBasicBlock(exitBlock);
|
function->addBasicBlock(exitBlock);
|
||||||
builder.setPosition(exitBlock, exitBlock->end());
|
builder.setPosition(exitBlock, exitBlock->end());
|
||||||
|
// CSE清除缓存
|
||||||
|
enterNewBasicBlock();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
builder.pushTrueBlock(thenBlock);
|
builder.pushTrueBlock(thenBlock);
|
||||||
builder.pushFalseBlock(exitBlock);
|
builder.pushFalseBlock(exitBlock);
|
||||||
@@ -1293,7 +1461,9 @@ std::any SysYIRGenerator::visitIfStmt(SysYParser::IfStmtContext *ctx) {
|
|||||||
labelstring.str("");
|
labelstring.str("");
|
||||||
function->addBasicBlock(thenBlock);
|
function->addBasicBlock(thenBlock);
|
||||||
builder.setPosition(thenBlock, thenBlock->end());
|
builder.setPosition(thenBlock, thenBlock->end());
|
||||||
|
// CSE清除缓存
|
||||||
|
enterNewBasicBlock();
|
||||||
|
|
||||||
auto block = dynamic_cast<SysYParser::BlockStmtContext *>(ctx->stmt(0));
|
auto block = dynamic_cast<SysYParser::BlockStmtContext *>(ctx->stmt(0));
|
||||||
if (block != nullptr) {
|
if (block != nullptr) {
|
||||||
visitBlockStmt(block);
|
visitBlockStmt(block);
|
||||||
@@ -1310,6 +1480,9 @@ std::any SysYIRGenerator::visitIfStmt(SysYParser::IfStmtContext *ctx) {
|
|||||||
labelstring.str("");
|
labelstring.str("");
|
||||||
function->addBasicBlock(exitBlock);
|
function->addBasicBlock(exitBlock);
|
||||||
builder.setPosition(exitBlock, exitBlock->end());
|
builder.setPosition(exitBlock, exitBlock->end());
|
||||||
|
// CSE清除缓存
|
||||||
|
enterNewBasicBlock();
|
||||||
|
|
||||||
}
|
}
|
||||||
return std::any();
|
return std::any();
|
||||||
}
|
}
|
||||||
@@ -1327,7 +1500,9 @@ std::any SysYIRGenerator::visitWhileStmt(SysYParser::WhileStmtContext *ctx) {
|
|||||||
builder.createUncondBrInst(headBlock);
|
builder.createUncondBrInst(headBlock);
|
||||||
BasicBlock::conectBlocks(curBlock, headBlock);
|
BasicBlock::conectBlocks(curBlock, headBlock);
|
||||||
builder.setPosition(headBlock, headBlock->end());
|
builder.setPosition(headBlock, headBlock->end());
|
||||||
|
// CSE清除缓存
|
||||||
|
enterNewBasicBlock();
|
||||||
|
|
||||||
BasicBlock* bodyBlock = new BasicBlock(function);
|
BasicBlock* bodyBlock = new BasicBlock(function);
|
||||||
BasicBlock* exitBlock = new BasicBlock(function);
|
BasicBlock* exitBlock = new BasicBlock(function);
|
||||||
|
|
||||||
@@ -1343,6 +1518,8 @@ std::any SysYIRGenerator::visitWhileStmt(SysYParser::WhileStmtContext *ctx) {
|
|||||||
labelstring.str("");
|
labelstring.str("");
|
||||||
function->addBasicBlock(bodyBlock);
|
function->addBasicBlock(bodyBlock);
|
||||||
builder.setPosition(bodyBlock, bodyBlock->end());
|
builder.setPosition(bodyBlock, bodyBlock->end());
|
||||||
|
// CSE清除缓存
|
||||||
|
enterNewBasicBlock();
|
||||||
|
|
||||||
builder.pushBreakBlock(exitBlock);
|
builder.pushBreakBlock(exitBlock);
|
||||||
builder.pushContinueBlock(headBlock);
|
builder.pushContinueBlock(headBlock);
|
||||||
@@ -1367,7 +1544,9 @@ std::any SysYIRGenerator::visitWhileStmt(SysYParser::WhileStmtContext *ctx) {
|
|||||||
labelstring.str("");
|
labelstring.str("");
|
||||||
function->addBasicBlock(exitBlock);
|
function->addBasicBlock(exitBlock);
|
||||||
builder.setPosition(exitBlock, exitBlock->end());
|
builder.setPosition(exitBlock, exitBlock->end());
|
||||||
|
// CSE清除缓存
|
||||||
|
enterNewBasicBlock();
|
||||||
|
|
||||||
return std::any();
|
return std::any();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1482,62 +1661,34 @@ std::any SysYIRGenerator::visitLValue(SysYParser::LValueContext *ctx) {
|
|||||||
|
|
||||||
// 3. 处理可变变量 (AllocaInst/GlobalValue) 或带非常量索引的常量变量
|
// 3. 处理可变变量 (AllocaInst/GlobalValue) 或带非常量索引的常量变量
|
||||||
// 这里区分标量访问和数组元素/子数组访问
|
// 这里区分标量访问和数组元素/子数组访问
|
||||||
|
Value *targetAddress = nullptr;
|
||||||
// 检查是否是访问标量变量本身(没有索引,且声明维度为0)
|
// 检查是否是访问标量变量本身(没有索引,且声明维度为0)
|
||||||
if (dims.empty() && declaredNumDims == 0) {
|
if (dims.empty() && declaredNumDims == 0) {
|
||||||
// 对于标量变量,直接加载其值。
|
|
||||||
// variable 本身就是指向标量的指针 (e.g., int* %a)
|
|
||||||
if (dynamic_cast<AllocaInst*>(variable) || dynamic_cast<GlobalValue*>(variable)) {
|
if (dynamic_cast<AllocaInst*>(variable) || dynamic_cast<GlobalValue*>(variable)) {
|
||||||
value = builder.createLoadInst(variable);
|
targetAddress = variable;
|
||||||
} else {
|
} else {
|
||||||
// 如果走到这里且不是AllocaInst/GlobalValue,但dims为空且declaredNumDims为0,
|
|
||||||
// 且又不是ConstantVariable (前面已处理),则可能是错误情况。
|
|
||||||
assert(false && "Unhandled scalar variable type in LValue access.");
|
assert(false && "Unhandled scalar variable type in LValue access.");
|
||||||
return static_cast<Value*>(nullptr);
|
return static_cast<Value*>(nullptr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 访问数组元素或子数组(有索引,或变量本身是数组/多维指针)
|
|
||||||
Value* gepBasePointer = nullptr;
|
Value* gepBasePointer = nullptr;
|
||||||
std::vector<Value*> gepIndices; // 准备传递给 getGEPAddressInst 的索引列表
|
std::vector<Value*> gepIndices;
|
||||||
// GEP 的基指针就是变量本身(它是一个指向内存的指针)
|
|
||||||
if (AllocaInst *alloc = dynamic_cast<AllocaInst *>(variable)) {
|
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();
|
Type* allocatedType = alloc->getType()->as<PointerType>()->getBaseType();
|
||||||
|
|
||||||
if (allocatedType->isPointer()) {
|
if (allocatedType->isPointer()) {
|
||||||
// 如果 AllocaInst 分配的是一个指针类型 (例如,用于存储函数参数的指针,如 int b[][20] 中的 b)
|
gepBasePointer = builder.createLoadInst(alloc);
|
||||||
// 即 `allocatedType` 是一个指向数组指针的指针 (e.g., [20 x i32]**)
|
|
||||||
// 那么 GEP 的基指针是加载这个指针变量的值。
|
|
||||||
gepBasePointer = builder.createLoadInst(alloc); // 加载出实际的指针值 (e.g., [20 x i32]*)
|
|
||||||
// 对于这种参数指针,用户提供的索引直接作用于它。不需要额外的 0。
|
|
||||||
gepIndices = dims;
|
gepIndices = dims;
|
||||||
} else {
|
} else {
|
||||||
// 如果 AllocaInst 分配的是实际的数组数据 (例如,int b[10][20] 中的 b)
|
gepBasePointer = alloc;
|
||||||
// 那么 AllocaInst 本身就是 GEP 的基指针。
|
|
||||||
// 这里的 `alloc` 是指向数组的指针 (e.g., [10 x [20 x i32]]*)
|
|
||||||
gepBasePointer = alloc; // 类型是 [10 x [20 x i32]]*
|
|
||||||
// 对于这种完整的数组分配,GEP 的第一个索引必须是 0,用于“步过”整个数组。
|
|
||||||
gepIndices.push_back(ConstantInteger::get(0));
|
gepIndices.push_back(ConstantInteger::get(0));
|
||||||
gepIndices.insert(gepIndices.end(), dims.begin(), dims.end());
|
gepIndices.insert(gepIndices.end(), dims.begin(), dims.end());
|
||||||
}
|
}
|
||||||
} else if (GlobalValue *glob = dynamic_cast<GlobalValue *>(variable)) {
|
} else if (GlobalValue *glob = dynamic_cast<GlobalValue *>(variable)) {
|
||||||
// 情况 B: 全局变量 (GlobalValue)
|
gepBasePointer = glob;
|
||||||
// GlobalValue 总是指向全局数据的指针。
|
|
||||||
gepBasePointer = glob; // 类型是 [61 x [67 x i32]]*
|
|
||||||
// 对于全局数组,GEP 的第一个索引必须是 0,用于“步过”整个数组。
|
|
||||||
gepIndices.push_back(ConstantInteger::get(0));
|
gepIndices.push_back(ConstantInteger::get(0));
|
||||||
gepIndices.insert(gepIndices.end(), dims.begin(), dims.end());
|
gepIndices.insert(gepIndices.end(), dims.begin(), dims.end());
|
||||||
} else if (ConstantVariable *constV = dynamic_cast<ConstantVariable *>(variable)) {
|
} else if (ConstantVariable *constV = dynamic_cast<ConstantVariable *>(variable)) {
|
||||||
// 情况 C: 常量变量 (ConstantVariable),如果它代表全局数组常量
|
|
||||||
// 假设 ConstantVariable 可以直接作为 GEP 的基指针。
|
|
||||||
gepBasePointer = constV;
|
gepBasePointer = constV;
|
||||||
// 对于常量数组,也需要 0 索引来“步过”整个数组。
|
|
||||||
// 这里可以进一步检查 constV->getType()->as<PointerType>()->getBaseType()->isArray()
|
|
||||||
// 但为了简洁,假设所有 ConstantVariable 作为 GEP 基指针时都需要此 0。
|
|
||||||
gepIndices.push_back(ConstantInteger::get(0));
|
gepIndices.push_back(ConstantInteger::get(0));
|
||||||
gepIndices.insert(gepIndices.end(), dims.begin(), dims.end());
|
gepIndices.insert(gepIndices.end(), dims.begin(), dims.end());
|
||||||
} else {
|
} else {
|
||||||
@@ -1545,18 +1696,25 @@ std::any SysYIRGenerator::visitLValue(SysYParser::LValueContext *ctx) {
|
|||||||
return static_cast<Value *>(nullptr);
|
return static_cast<Value *>(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 现在调用 getGEPAddressInst,传入正确准备的基指针和索引列表
|
targetAddress = getGEPAddressInst(gepBasePointer, gepIndices);
|
||||||
Value *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 {
|
} else {
|
||||||
// 否则,表示访问的是最终的标量元素,加载其值
|
// 缓存未命中,创建新的 LoadInst
|
||||||
// 假设 createLoadInst 接受 Value* pointer
|
value = builder.createLoadInst(targetAddress);
|
||||||
value = builder.createLoadInst(targetAddress);
|
availableLoads[targetAddress] = value; // 将新的 LoadInst 结果加入缓存
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1676,6 +1834,7 @@ std::any SysYIRGenerator::visitUnaryExp(SysYParser::UnaryExpContext *ctx) {
|
|||||||
visitPrimaryExp(ctx->primaryExp());
|
visitPrimaryExp(ctx->primaryExp());
|
||||||
} else if (ctx->call() != nullptr) {
|
} else if (ctx->call() != nullptr) {
|
||||||
BinaryExpStack.push_back(std::any_cast<Value *>(visitCall(ctx->call())));BinaryExpLenStack.back()++;
|
BinaryExpStack.push_back(std::any_cast<Value *>(visitCall(ctx->call())));BinaryExpLenStack.back()++;
|
||||||
|
invalidateExpressionsOnCall();
|
||||||
} else if (ctx->unaryOp() != nullptr) {
|
} else if (ctx->unaryOp() != nullptr) {
|
||||||
// 遇到一元操作符,将其压入 BinaryExpStack
|
// 遇到一元操作符,将其压入 BinaryExpStack
|
||||||
auto opNode = dynamic_cast<antlr4::tree::TerminalNode*>(ctx->unaryOp()->children[0]);
|
auto opNode = dynamic_cast<antlr4::tree::TerminalNode*>(ctx->unaryOp()->children[0]);
|
||||||
|
|||||||
Reference in New Issue
Block a user