[midend-llvmirprint]修复进度(162/199),修复若干打印问题,修复若干ir生成逻辑问题
This commit is contained in:
@@ -1360,11 +1360,12 @@ std::any SysYIRGenerator::visitAssignStmt(SysYParser::AssignStmtContext *ctx) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (LType == Type::getFloatType()) {
|
||||
if (LType == Type::getFloatType() && RType != Type::getFloatType()) {
|
||||
RValue = builder.createItoFInst(RValue);
|
||||
} else { // 假设如果不是浮点型,就是整型
|
||||
} else if (LType != Type::getFloatType() && RType == Type::getFloatType()) {
|
||||
RValue = builder.createFtoIInst(RValue);
|
||||
}
|
||||
// 如果两者都是同一类型,就不需要转换
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1691,8 +1692,10 @@ std::any SysYIRGenerator::visitLValue(SysYParser::LValueContext *ctx) {
|
||||
gepBasePointer = alloc;
|
||||
gepIndices.push_back(ConstantInteger::get(0));
|
||||
if (dims.empty() && declaredNumDims > 0) {
|
||||
// 数组名单独出现(没有索引):在SysY中,数组名应该退化为指向第一个元素的指针
|
||||
// 需要添加额外的0索引来获取第一个元素的地址
|
||||
// 数组名单独出现(没有索引):在SysY中,多维数组名应该退化为指向第一行的指针
|
||||
// 对于二维数组 T[M][N],退化为 T(*)[N],需要GEP: getelementptr T[M][N], T[M][N]* ptr, i32 0, i32 0
|
||||
// 第一个i32 0: 选择数组本身,第二个i32 0: 选择第0行
|
||||
// 结果类型: T[N]*
|
||||
gepIndices.push_back(ConstantInteger::get(0));
|
||||
} else {
|
||||
// 正常的数组元素访问
|
||||
@@ -1703,7 +1706,8 @@ std::any SysYIRGenerator::visitLValue(SysYParser::LValueContext *ctx) {
|
||||
gepBasePointer = glob;
|
||||
gepIndices.push_back(ConstantInteger::get(0));
|
||||
if (dims.empty() && declaredNumDims > 0) {
|
||||
// 全局数组名单独出现(没有索引):应该退化为指向第一个元素的指针
|
||||
// 全局数组名单独出现(没有索引):应该退化为指向第一行的指针
|
||||
// 需要添加一个额外的i32 0索引
|
||||
gepIndices.push_back(ConstantInteger::get(0));
|
||||
} else {
|
||||
// 正常的数组元素访问
|
||||
@@ -1713,7 +1717,8 @@ std::any SysYIRGenerator::visitLValue(SysYParser::LValueContext *ctx) {
|
||||
gepBasePointer = constV;
|
||||
gepIndices.push_back(ConstantInteger::get(0));
|
||||
if (dims.empty() && declaredNumDims > 0) {
|
||||
// 常量数组名单独出现(没有索引):应该退化为指向第一个元素的指针
|
||||
// 常量数组名单独出现(没有索引):应该退化为指向第一行的指针
|
||||
// 需要添加一个额外的i32 0索引
|
||||
gepIndices.push_back(ConstantInteger::get(0));
|
||||
} else {
|
||||
// 正常的数组元素访问
|
||||
@@ -1835,15 +1840,27 @@ std::any SysYIRGenerator::visitCall(SysYParser::CallContext *ctx) {
|
||||
} else if (formalParamExpectedValueType->isFloat() && actualArgType->isInt()) {
|
||||
args[i] = builder.createItoFInst(args[i]);
|
||||
}
|
||||
// 2. 指针类型转换 (例如数组退化:`[N x T]*` 到 `T*`,或兼容指针类型之间) TODO:不清楚有没有这种样例
|
||||
// 2. 指针类型转换 (例如数组退化:`[N x T]*` 到 `T*`,或兼容指针类型之间)
|
||||
// 这种情况常见于数组参数,实参可能是一个更具体的数组指针类型,
|
||||
// 而形参是其退化后的基础指针类型。LLVM 的 `bitcast` 指令可以用于
|
||||
// 在相同大小的指针类型之间进行转换,这对于数组退化至关重要。
|
||||
// else if (formalParamType->isPointer() && actualArgType->isPointer()) {
|
||||
// 检查指针基类型是否兼容,或者是否是数组退化导致的类型不同。
|
||||
// 使用 bitcast,
|
||||
// args[i] = builder.createBitCastInst(args[i], formalParamType);
|
||||
// }
|
||||
// 而形参是其退化后的基础指针类型。
|
||||
else if (formalParamExpectedValueType->isPointer() && actualArgType->isPointer()) {
|
||||
// 检查是否是数组指针到元素指针的decay
|
||||
// 例如:[N x T]* -> T*
|
||||
auto formalPtrType = formalParamExpectedValueType->as<PointerType>();
|
||||
auto actualPtrType = actualArgType->as<PointerType>();
|
||||
|
||||
if (formalPtrType && actualPtrType && actualPtrType->getBaseType()->isArray()) {
|
||||
auto actualArrayType = actualPtrType->getBaseType()->as<ArrayType>();
|
||||
if (actualArrayType &&
|
||||
formalPtrType->getBaseType() == actualArrayType->getElementType()) {
|
||||
// 这是数组decay的情况,添加GEP来获取数组的第一个元素
|
||||
std::vector<Value*> indices;
|
||||
indices.push_back(ConstantInteger::get(0)); // 第一个索引:解引用指针
|
||||
indices.push_back(ConstantInteger::get(0)); // 第二个索引:获取数组第一个元素
|
||||
args[i] = getGEPAddressInst(args[i], indices);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3. 其他未预期的类型不匹配
|
||||
// 如果代码执行到这里,说明存在编译器前端未处理的类型不兼容或错误。
|
||||
else {
|
||||
@@ -2227,15 +2244,23 @@ void Utils::createExternalFunction(
|
||||
const std::vector<std::string> ¶mNames,
|
||||
const std::vector<std::vector<Value *>> ¶mDims, Type *returnType,
|
||||
const std::string &funcName, Module *pModule, IRBuilder *pBuilder) {
|
||||
auto funcType = Type::getFunctionType(returnType, paramTypes);
|
||||
// 根据paramDims调整参数类型,数组参数需要转换为指针类型
|
||||
std::vector<Type *> adjustedParamTypes = paramTypes;
|
||||
for (int i = 0; i < paramTypes.size() && i < paramDims.size(); ++i) {
|
||||
if (!paramDims[i].empty()) {
|
||||
// 如果参数有维度信息,说明是数组参数,转换为指针类型
|
||||
adjustedParamTypes[i] = Type::getPointerType(paramTypes[i]);
|
||||
}
|
||||
}
|
||||
auto funcType = Type::getFunctionType(returnType, adjustedParamTypes);
|
||||
auto function = pModule->createExternalFunction(funcName, funcType);
|
||||
auto entry = function->getEntryBlock();
|
||||
pBuilder->setPosition(entry, entry->end());
|
||||
|
||||
for (int i = 0; i < paramTypes.size(); ++i) {
|
||||
auto arg = new Argument(paramTypes[i], function, i, paramNames[i]);
|
||||
auto arg = new Argument(adjustedParamTypes[i], function, i, paramNames[i]);
|
||||
auto alloca = pBuilder->createAllocaInst(
|
||||
Type::getPointerType(paramTypes[i]), paramNames[i]);
|
||||
Type::getPointerType(adjustedParamTypes[i]), paramNames[i]);
|
||||
function->insertArgument(arg);
|
||||
auto store = pBuilder->createStoreInst(arg, alloca);
|
||||
pModule->addVariable(paramNames[i], alloca);
|
||||
|
||||
Reference in New Issue
Block a user