[midend-mem2reg]Reg2Mem建立完成runit测试127/140,reg2mem基本思路:函数参数默认降级到内存,有结果的指令被降级的内存
This commit is contained in:
@ -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<Argument *>(val) || dynamic_cast<Instruction *>(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<AllocaInst*>(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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<ConstantValue *>(returnValue);
|
||||
if (constValue != nullptr) {
|
||||
if (funcType == Type::getFloatType()) {
|
||||
|
||||
@ -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<PointerType *>(allocaInst->getType())->getBaseType();
|
||||
// auto allocatedType = dynamic_cast<PointerType *>(allocaInst->getType())->getBaseType();
|
||||
auto allocatedType = allocaInst->getAllocatedType();
|
||||
printType(allocatedType);
|
||||
|
||||
// 仍然打印维度信息,如果存在的话
|
||||
|
||||
Reference in New Issue
Block a user