Merge branch 'midend' into backend-IRC

This commit is contained in:
Lixuanwang
2025-08-02 12:47:27 +08:00

View File

@@ -653,7 +653,44 @@ std::any SysYIRGenerator::visitConstDecl(SysYParser::ConstDeclContext *ctx) {
Value *currentValue = counterValues[k]; Value *currentValue = counterValues[k];
unsigned currentRepeatNum = counterNumbers[k]; unsigned currentRepeatNum = counterNumbers[k];
// 检查是否是0并且重复次数足够大例如 >16才用 memset
if (ConstantInteger *constInt = dynamic_cast<ConstantInteger *>(currentValue)) {
if (constInt->getInt() == 0 && currentRepeatNum >= 16) { // 阈值可调整如16、32等
// 计算 memset 的起始地址(基于当前线性偏移量)
std::vector<Value *> memsetStartIndices;
int tempLinearIndex = linearIndexOffset;
// 将线性索引转换为多维索引
for (int dimIdx = dimSizes.size() - 1; dimIdx >= 0; --dimIdx) {
memsetStartIndices.insert(memsetStartIndices.begin(),
ConstantInteger::get(static_cast<int>(tempLinearIndex % dimSizes[dimIdx])));
tempLinearIndex /= dimSizes[dimIdx];
}
// 构造 GEP 计算 memset 的起始地址
std::vector<Value *> gepIndicesForMemset;
gepIndicesForMemset.push_back(ConstantInteger::get(0)); // 跳过 alloca 类型
gepIndicesForMemset.insert(gepIndicesForMemset.end(), memsetStartIndices.begin(),
memsetStartIndices.end());
Value *memsetPtr = builder.createGetElementPtrInst(alloca, gepIndicesForMemset);
// 计算 memset 的字节数 = 元素个数 × 元素大小
Type *elementType = type;;
uint64_t elementSize = elementType->getSize();
Value *size = ConstantInteger::get(currentRepeatNum * elementSize);
// 生成 memset 指令(假设你的 IRBuilder 有 createMemset 方法)
builder.createMemsetInst(memsetPtr, ConstantInteger::get(0), size, ConstantInteger::get(0));
// 跳过这些已处理的0
linearIndexOffset += currentRepeatNum;
continue; // 直接进入下一次循环
}
}
for (unsigned i = 0; i < currentRepeatNum; ++i) { for (unsigned i = 0; i < currentRepeatNum; ++i) {
// 对于非零值,生成对应的 store 指令
std::vector<Value *> currentIndices; std::vector<Value *> currentIndices;
int tempLinearIndex = linearIndexOffset + i; // 使用偏移量和当前重复次数内的索引 int tempLinearIndex = linearIndexOffset + i; // 使用偏移量和当前重复次数内的索引
@@ -767,7 +804,42 @@ std::any SysYIRGenerator::visitVarDecl(SysYParser::VarDeclContext *ctx) {
// 当前 Value 的值和重复次数 // 当前 Value 的值和重复次数
Value *currentValue = counterValues[k]; Value *currentValue = counterValues[k];
unsigned currentRepeatNum = counterNumbers[k]; unsigned currentRepeatNum = counterNumbers[k];
// 检查是否是0并且重复次数足够大例如 >16才用 memset
if (ConstantInteger *constInt = dynamic_cast<ConstantInteger *>(currentValue)) {
if (constInt->getInt() == 0 && currentRepeatNum >= 16) { // 阈值可调整如16、32等
// 计算 memset 的起始地址(基于当前线性偏移量)
std::vector<Value *> memsetStartIndices;
int tempLinearIndex = linearIndexOffset;
// 将线性索引转换为多维索引
for (int dimIdx = dimSizes.size() - 1; dimIdx >= 0; --dimIdx) {
memsetStartIndices.insert(memsetStartIndices.begin(),
ConstantInteger::get(static_cast<int>(tempLinearIndex % dimSizes[dimIdx])));
tempLinearIndex /= dimSizes[dimIdx];
}
// 构造 GEP 计算 memset 的起始地址
std::vector<Value *> gepIndicesForMemset;
gepIndicesForMemset.push_back(ConstantInteger::get(0)); // 跳过 alloca 类型
gepIndicesForMemset.insert(gepIndicesForMemset.end(), memsetStartIndices.begin(),
memsetStartIndices.end());
Value *memsetPtr = builder.createGetElementPtrInst(alloca, gepIndicesForMemset);
// 计算 memset 的字节数 = 元素个数 × 元素大小
Type *elementType = type;
;
uint64_t elementSize = elementType->getSize();
Value *size = ConstantInteger::get(currentRepeatNum * elementSize);
// 生成 memset 指令(假设你的 IRBuilder 有 createMemset 方法)
builder.createMemsetInst(memsetPtr, ConstantInteger::get(0), size, ConstantInteger::get(0));
// 跳过这些已处理的0
linearIndexOffset += currentRepeatNum;
continue; // 直接进入下一次循环
}
}
for (unsigned i = 0; i < currentRepeatNum; ++i) { for (unsigned i = 0; i < currentRepeatNum; ++i) {
std::vector<Value *> currentIndices; std::vector<Value *> currentIndices;
int tempLinearIndex = linearIndexOffset + i; // 使用偏移量和当前重复次数内的索引 int tempLinearIndex = linearIndexOffset + i; // 使用偏移量和当前重复次数内的索引
@@ -793,7 +865,6 @@ std::any SysYIRGenerator::visitVarDecl(SysYParser::VarDeclContext *ctx) {
// 更新线性索引偏移量,以便下一次迭代从正确的位置开始 // 更新线性索引偏移量,以便下一次迭代从正确的位置开始
linearIndexOffset += currentRepeatNum; linearIndexOffset += currentRepeatNum;
} }
} }
} }
} }
@@ -895,7 +966,7 @@ std::any SysYIRGenerator::visitFuncDef(SysYParser::FuncDefContext *ctx){
currentParamDims.push_back(ConstantInteger::get(-1)); // 标记第一个维度为未知 currentParamDims.push_back(ConstantInteger::get(-1)); // 标记第一个维度为未知
for (const auto &exp : param->exp()) { for (const auto &exp : param->exp()) {
// 访问表达式以获取维度大小,这些维度必须是常量 // 访问表达式以获取维度大小,这些维度必须是常量
Value* dimVal = std::any_cast<Value *>(visitExp(exp)); Value* dimVal = computeExp(exp);
// 确保维度是常量整数,否则 buildArrayType 会断言失败 // 确保维度是常量整数,否则 buildArrayType 会断言失败
assert(dynamic_cast<ConstantInteger*>(dimVal) && "Array dimension in parameter must be a constant integer!"); assert(dynamic_cast<ConstantInteger*>(dimVal) && "Array dimension in parameter must be a constant integer!");
currentParamDims.push_back(dimVal); currentParamDims.push_back(dimVal);