diff --git a/src/Reg2Mem.cpp b/src/Reg2Mem.cpp index e82af20..19e2e91 100644 --- a/src/Reg2Mem.cpp +++ b/src/Reg2Mem.cpp @@ -1,5 +1,6 @@ #include "Reg2Mem.h" -#include "SysYIROptUtils.h" // 如果有的话 +#include "SysYIROptUtils.h" +#include "SysYIRPrinter.h" extern int DEBUG; // 全局调试标志 @@ -33,15 +34,15 @@ void Reg2MemContext::run(Function *func) { bool Reg2MemContext::isPromotableToMemory(Value *val) { // 参数和指令结果是 SSA 值 if(DEBUG){ - if(val->getName() == ""){ - assert(false && "Value name should not be empty in Reg2MemContext::isPromotableToMemory"); - } - std::cout << "Checking if value is promotable to memory: " << val->getName() << std::endl; + // if(val->getName() == ""){ + // assert(false && "Value name should not be empty in Reg2MemContext::isPromotableToMemory"); + // } + // std::cout << "Checking if value is promotable to memory: " << val->getName() << std::endl; } if (dynamic_cast(val) || dynamic_cast(val)) { // 如果值已经是指针类型,则通常不为其分配额外的内存,因为它已经是一个地址。 // (除非我们想将其值也存储起来,这通常不用于 Reg2Mem) - // Reg2Mem 关注的是将非指针值从寄存器语义转换为内存语义。 + // // Reg2Mem 关注的是将非指针值从寄存器语义转换为内存语义。 if (val->getType()->isPointer()) { return false; } @@ -60,9 +61,10 @@ void Reg2MemContext::allocateMemoryForSSAValues(Function *func) { // 1. 为函数参数分配内存 builder->setPosition(entryBlock, entryBlock->begin()); // 确保在入口块的开始位置插入 for (auto arg : func->getArguments()) { - if (isPromotableToMemory(arg)) { + // 默认情况下,将所有参数是提升到内存 + // if (isPromotableToMemory(arg)) { // 参数的类型就是 AllocaInst 需要分配的类型 - AllocaInst *alloca = builder->createAllocaInst(arg->getType(), {}); + AllocaInst *alloca = builder->createAllocaInst(Type::getPointerType(arg->getType()), {}, arg->getName() + ".reg2mem"); // 将参数值 store 到 alloca 中 (这是 Mem2Reg 逆转的关键一步) builder->createStoreInst(arg, alloca); valueToAllocaMap[arg] = alloca; @@ -71,17 +73,19 @@ void Reg2MemContext::allocateMemoryForSSAValues(Function *func) { // 通常 alloca 都在 entry block 的最开始 // 这里我们只是创建,并让 builder 决定插入位置 (通常在当前插入点) // 如果需要严格控制顺序,可能需要手动 insert 到 instruction list - } + // } } // 2. 为指令结果分配内存 // 遍历所有基本块和指令,找出所有需要分配 Alloca 的指令结果 for (auto &bb : func->getBasicBlocks()) { for (auto &inst : bb->getInstructions_Range()) { + // SysYPrinter::printInst(inst.get()); // 只有有结果的指令才可能需要分配内存 // (例如 BinaryInst, CallInst, LoadInst, PhiInst 等) // StoreInst, BranchInst, ReturnInst 等没有结果的指令不需要 - if (inst.get()->getType()->isVoid()) { // 没有返回值的指令 + + if (dynamic_cast(inst.get()) || inst.get()->getType()->isVoid()) { continue; } @@ -90,7 +94,7 @@ void Reg2MemContext::allocateMemoryForSSAValues(Function *func) { // AllocaInst 应该在入口块,而不是当前指令所在块 // 这里我们只是创建,并稍后调整其位置 // 通常的做法是在循环结束后统一将 alloca 放到 entryBlock 的顶部 - AllocaInst *alloca = builder->createAllocaInst(inst.get()->getType(), {}); + AllocaInst *alloca = builder->createAllocaInst(Type::getPointerType(inst.get()->getType()), {}, inst.get()->getName() + ".reg2mem"); valueToAllocaMap[inst.get()] = alloca; } } diff --git a/src/SysYIRGenerator.cpp b/src/SysYIRGenerator.cpp index 1fb7305..2fa2be8 100644 --- a/src/SysYIRGenerator.cpp +++ b/src/SysYIRGenerator.cpp @@ -712,7 +712,7 @@ std::any SysYIRGenerator::visitReturnStmt(SysYParser::ReturnStmtContext *ctx) { } Type* funcType = builder.getBasicBlock()->getParent()->getReturnType(); - if (funcType!= returnValue->getType() && returnValue != nullptr) { + if (returnValue != nullptr && funcType!= returnValue->getType()) { ConstantValue * constValue = dynamic_cast(returnValue); if (constValue != nullptr) { if (funcType == Type::getFloatType()) { diff --git a/src/SysYIRPrinter.cpp b/src/SysYIRPrinter.cpp index 9cfc6a6..877e4ab 100644 --- a/src/SysYIRPrinter.cpp +++ b/src/SysYIRPrinter.cpp @@ -364,7 +364,8 @@ void SysYPrinter::printInst(Instruction *pInst) { // AllocaInst 的类型现在应该是一个 PointerType,指向正确的 ArrayType 或 ScalarType // 例如:alloca i32, align 4 或者 alloca [10 x i32], align 4 - auto allocatedType = dynamic_cast(allocaInst->getType())->getBaseType(); + // auto allocatedType = dynamic_cast(allocaInst->getType())->getBaseType(); + auto allocatedType = allocaInst->getAllocatedType(); printType(allocatedType); // 仍然打印维度信息,如果存在的话