This commit is contained in:
rain2133
2025-07-20 12:54:19 +08:00
parent 8f1e477e73
commit 20cd16bf52

View File

@@ -10,10 +10,9 @@
#include <sstream>
#include <string>
#include <vector>
using namespace std;
#include "SysYIRGenerator.h"
using namespace std;
namespace sysy {
/*
@@ -130,30 +129,111 @@ std::any SysYIRGenerator::visitVarDecl(SysYParser::VarDeclContext *ctx) {
delete root;
if (dims.empty()) {
builder.createStoreInst(values.getValue(0), alloca);
} else {
// 对于多维数组使用memset初始化
// 计算每个维度的大小
// 这里的values.getNumbers()返回的是每个维度的大小
// 这里的values.getValues()返回的是每个维度对应的值
// 例如对于一个二维数组values.getNumbers()可能是[3, 4]表示3行4列
// values.getValues()可能是[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
// 对于每个维度使用memset将对应的值填充到数组中
// 这里的alloca是一个指向数组的指针
const std::vector<unsigned int> & counterNumbers = values.getNumbers();
const std::vector<sysy::Value *> & counterValues = values.getValues();
unsigned begin = 0;
for (size_t i = 0; i < counterNumbers.size(); i++) {
} else{
// **数组变量初始化**
const std::vector<sysy::Value *> &counterValues = values.getValues();
// 计算数组的**总元素数量**和**总字节大小**
int numElements = 1;
// 存储每个维度的实际整数大小,用于索引计算
std::vector<int> dimSizes;
for (Value *dimVal : dims) {
if (ConstantInteger *constInt = dynamic_cast<ConstantInteger *>(dimVal)) {
int dimSize = constInt->getInt();
numElements *= dimSize;
dimSizes.push_back(dimSize);
}
// TODO else 错误处理:数组维度必须是常量(对于静态分配)
}
unsigned int elementSizeInBytes = type->getSize(); // 获取单个元素的大小(字节)
unsigned int totalSizeInBytes = numElements * elementSizeInBytes;
// **判断是否可以进行全零初始化优化**
bool allValuesAreZero = false;
if (counterValues.empty()) { // 例如 int arr[3] = {}; 或 int arr[3][4] = {};
allValuesAreZero = true;
}
else {
allValuesAreZero = true;
for (Value *val : counterValues){
if (ConstantInteger *constInt = dynamic_cast<ConstantInteger *>(val)){
if (constInt->getInt() != 0){
allValuesAreZero = false;
break;
}
}
else{
// 如果值不是常量,我们通常不能确定它是否为零,所以不进行 memset 优化
allValuesAreZero = false;
break;
}
}
}
if (allValuesAreZero) {
// 如果所有初始化值都是零(或没有明确初始化但语法允许),使用 memset 优化
builder.createMemsetInst(
alloca, ConstantInteger::get(begin),
ConstantInteger::get(static_cast<int>(counterNumbers[i])),
counterValues[i]);
begin += counterNumbers[i];
alloca, // 目标数组的起始地址
ConstantInteger::get(0), // 偏移量通常为0后续删除
ConstantInteger::get(totalSizeInBytes),
ConstantInteger::get(0)); // 填充的总字节数
}
else {
// **逐元素存储:遍历所有初始值,并为每个值生成一个 store 指令**
for (size_t k = 0; k < counterValues.size(); ++k) {
// 用于存储当前元素的索引列表
std::vector<Value *> currentIndices;
int tempLinearIndex = k; // 临时线性索引,用于计算多维索引
// **将线性索引转换为多维索引**
// 这个循环从最内层维度开始倒推,计算每个维度的索引
// 假设是行主序row-major order这是 C/C++ 数组的标准存储方式
for (int dimIdx = dimSizes.size() - 1; dimIdx >= 0; --dimIdx)
{
// 计算当前维度的索引,并插入到列表的最前面
currentIndices.insert(currentIndices.begin(),
ConstantInteger::get(static_cast<int>(tempLinearIndex % dimSizes[dimIdx])));
// 更新线性索引,用于计算下一个更高维度的索引
tempLinearIndex /= dimSizes[dimIdx];
}
// **生成 store 指令,传入值、基指针和计算出的索引列表**
// 你的 builder.createStoreInst 签名需要能够接受这些参数
// 假设你的 builder.createStoreInst(Value *val, Value *ptr, const std::vector<Value *> &indices, ...)
builder.createStoreInst(counterValues[k], alloca, currentIndices);
}
}
}
}
else
{ // **如果没有显式初始化值,默认对数组进行零初始化**
if (!dims.empty())
{ // 只有数组才需要默认的零初始化
int numElements = 1;
for (Value *dimVal : dims)
{
if (ConstantInteger *constInt = dynamic_cast<ConstantInteger *>(dimVal))
{
numElements *= constInt->getInt();
}
}
unsigned int elementSizeInBytes = type->getSize();
unsigned int totalSizeInBytes = numElements * elementSizeInBytes;
// 使用 memset 将整个数组清零
builder.createMemsetInst(
alloca,
ConstantInteger::get(0),
ConstantInteger::get(totalSizeInBytes),
ConstantInteger::get(0)
); // 填充的总字节数
}
// 标量变量如果没有初始化值,通常不生成额外的初始化指令,因为其内存已分配但未赋值。
}
module->addVariable(name, alloca);
}
return std::any();
}