diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 47d74ab..a052e5b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -22,7 +22,7 @@ add_executable(sysyc SysYIRGenerator.cpp SysYIRPrinter.cpp SysYIRCFGOpt.cpp - SysYIRAnalyser.cpp + # SysYIRAnalyser.cpp # DeadCodeElimination.cpp AddressCalculationExpansion.cpp # Mem2Reg.cpp diff --git a/src/IR.cpp b/src/IR.cpp index 5f4e0c5..c694839 100644 --- a/src/IR.cpp +++ b/src/IR.cpp @@ -49,6 +49,11 @@ auto Type::getFunctionType(Type *returnType, const std::vector ¶mTyp return FunctionType::get(returnType, paramTypes); } +auto Type::getArrayType(Type *elementType, unsigned numElements) -> Type * { + // forward to ArrayType + return ArrayType::get(elementType, numElements); +} + auto Type::getSize() const -> unsigned { switch (kind) { case kInt: @@ -58,6 +63,10 @@ auto Type::getSize() const -> unsigned { case kPointer: case kFunction: return 8; + case Kind::kArray: { + const ArrayType* arrType = static_cast(this); + return arrType->getElementType()->getSize() * arrType->getNumElements(); + } case kVoid: return 0; } @@ -95,6 +104,11 @@ FunctionType*FunctionType::get(Type *returnType, const std::vector ¶ return result.first->get(); } +ArrayType *ArrayType::get(Type *elementType, unsigned numElements) { + // TODO:可以考虑在这里添加缓存,避免重复创建相同的数组类型 + return new ArrayType(elementType, numElements); +} + void Value::replaceAllUsesWith(Value *value) { for (auto &use : uses) { use->getUser()->setOperand(use->getIndex(), value); @@ -465,44 +479,7 @@ Function * Function::clone(const std::string &suffix) const { break; } - case Instruction::kLa: { - auto oldLaInst = dynamic_cast(inst); - auto oldPointer = oldLaInst->getPointer(); - Value *newPointer; - std::vector newIndices; - newPointer = oldNewValueMap.at(oldPointer); - - for (const auto &index : oldLaInst->getIndices()) { - newIndices.emplace_back(oldNewValueMap.at(index->getValue())); - } - ss << oldLaInst->getName() << suffix; - auto newLaInst = new LaInst(newPointer, newIndices, oldNewBlockMap.at(oldLaInst->getParent()), ss.str()); - ss.str(""); - oldNewValueMap.emplace(oldLaInst, newLaInst); - break; - } - - case Instruction::kGetSubArray: { - auto oldGetSubArrayInst = dynamic_cast(inst); - auto oldFather = oldGetSubArrayInst->getFatherArray(); - auto oldChild = oldGetSubArrayInst->getChildArray(); - Value *newFather; - Value *newChild; - std::vector newIndices; - newFather = oldNewValueMap.at(oldFather); - newChild = oldNewValueMap.at(oldChild); - - for (const auto &index : oldGetSubArrayInst->getIndices()) { - newIndices.emplace_back(oldNewValueMap.at(index->getValue())); - } - ss << oldGetSubArrayInst->getName() << suffix; - auto newGetSubArrayInst = - new GetSubArrayInst(dynamic_cast(newFather), dynamic_cast(newChild), newIndices, - oldNewBlockMap.at(oldGetSubArrayInst->getParent()), ss.str()); - ss.str(""); - oldNewValueMap.emplace(oldGetSubArrayInst, newGetSubArrayInst); - break; - } + // TODO:复制GEP指令 case Instruction::kMemset: { auto oldMemsetInst = dynamic_cast(inst); diff --git a/src/SysYIRGenerator.cpp b/src/SysYIRGenerator.cpp index 40b5f59..6302aa5 100644 --- a/src/SysYIRGenerator.cpp +++ b/src/SysYIRGenerator.cpp @@ -15,6 +15,73 @@ using namespace std; namespace sysy { + +Type* SysYIRGenerator::buildArrayType(Type* baseType, const std::vector& dims){ + Type* currentType = baseType; + // 从最内层维度开始构建 ArrayType + // 例如对于 int arr[2][3],先处理 [3],再处理 [2] + // 注意:SysY 的 dims 是从最外层到最内层,所以我们需要反向迭代 + // 或者调整逻辑,使得从内到外构建 ArrayType + // 假设 dims 列表是 [dim1, dim2, dim3...] (例如 [2, 3] for int[2][3]) + // 我们需要从最内层维度开始向外构建 ArrayType + for (int i = dims.size() - 1; i >= 0; --i) { + // 维度大小必须是常量,否则无法构建 ArrayType + ConstantInteger* constDim = dynamic_cast(dims[i]); + if (constDim == nullptr) { + // 如果维度不是常量,可能需要特殊处理,例如将其视为指针 + // 对于函数参数 int arr[] 这种,第一个维度可以为未知 + // 在这里,我们假设所有声明的数组维度都是常量 + assert(false && "Array dimension must be a constant integer!"); + return nullptr; + } + unsigned dimSize = constDim->getInt(); + currentType = Type::getArrayType(currentType, dimSize); + } + return currentType; +} + +Value* SysYIRGenerator::getGEPAddressInst(Value* basePointer, const std::vector& indices) { + // 检查 basePointer 是否为指针类型 + if (!basePointer->getType()->isPointer()) { + assert(false && "GEP base pointer must be a pointer type!"); + } + + // 获取基指针所指向的实际类型 (例如 int* 指向 int, int[2][3]* 指向 int[2][3]) + Type* currentElementType = basePointer->getType()->as()->getBaseType(); + + std::vector actualGEPIndices; + // GEP 指令的第一个索引通常是0,用于“跳过”基指针指向的聚合类型本身,直接指向其第一个元素。 + // 例如,对于 AllocaInst 返回的 `int[2][3]*`,第一个 `0` 索引表示从数组的开始而不是指针本身开始索引。 + actualGEPIndices.push_back(ConstantInteger::get(0)); + + // 将用户提供的索引添加到 GEP 操作数中 + for (Value* index : indices) { + actualGEPIndices.push_back(index); + } + + // 根据索引链计算最终的元素类型 + Type* finalTargetType = currentElementType; + + // 遍历用户提供的索引(不包括我们添加的第一个0),逐步确定 GEP 的最终结果类型 + // 每个索引都“深入”一个维度 + for (size_t i = 0; i < indices.size(); ++i) { // 这里遍历的是用户提供的索引 + if (finalTargetType && finalTargetType->isArray()) { + finalTargetType = finalTargetType->as()->getElementType(); + } else { + // 如果索引链还在继续,但当前类型已经不是数组或聚合类型,这通常是一个错误 + // 或者表示访问的是标量,后续索引无效。此时,finalTargetType 已经是最终的标量类型,不能再深入。 + // 例如,对 int arr[5]; 访问 arr[i][j] (j 是多余的),这里会停止类型推断。 + break; + } + } + + // GEP 的结果总是指针类型,指向最终计算出的元素 + Type* gepResultType = Type::getPointerType(finalTargetType); + + // 创建 GEP 指令。假设 builder.createGetElementPtrInst 的签名为 + // (Type* resultType, Value* basePointer, const std::vector& indices) + return builder.createGetElementPtrInst(basePointer, actualGEPIndices); +} /* * @brief: visit compUnit * @details: @@ -118,24 +185,28 @@ std::any SysYIRGenerator::visitVarDecl(SysYParser::VarDeclContext *ctx) { } } + Type* variableType = type; + if (!dims.empty()) { // 如果有维度,说明是数组 + variableType = buildArrayType(type, dims); // 构建完整的 ArrayType + } + + // 对于数组,alloca 的类型将是指针指向数组类型,例如 `int[2][3]*` + // 对于标量,alloca 的类型将是指针指向标量类型,例如 `int*` AllocaInst* alloca = builder.createAllocaInst(Type::getPointerType(type), dims, name); if (varDef->initVal() != nullptr) { ValueCounter values; - // 这里的varDef->initVal()可能是ScalarInitValue或ArrayInitValue ArrayValueTree* root = std::any_cast(varDef->initVal()->accept(this)); Utils::tree2Array(type, root, dims, dims.size(), values, &builder); delete root; - if (dims.empty()) { + + if (dims.empty()) { // 标量变量初始化 builder.createStoreInst(values.getValue(0), alloca); - } else{ - // **数组变量初始化** + } else { // 数组变量初始化 const std::vector &counterValues = values.getValues(); - // 计算数组的**总元素数量**和**总字节大小** int numElements = 1; - // 存储每个维度的实际整数大小,用于索引计算 std::vector dimSizes; for (Value *dimVal : dims) { if (ConstantInteger *constInt = dynamic_cast(dimVal)) { @@ -145,12 +216,11 @@ std::any SysYIRGenerator::visitVarDecl(SysYParser::VarDeclContext *ctx) { } // TODO else 错误处理:数组维度必须是常量(对于静态分配) } - unsigned int elementSizeInBytes = type->getSize(); // 获取单个元素的大小(字节) + unsigned int elementSizeInBytes = type->getSize(); unsigned int totalSizeInBytes = numElements * elementSizeInBytes; - // **判断是否可以进行全零初始化优化** bool allValuesAreZero = false; - if (counterValues.empty()) { // 例如 int arr[3] = {}; 或 int arr[3][4] = {}; + if (counterValues.empty()) { allValuesAreZero = true; } else { @@ -163,7 +233,6 @@ std::any SysYIRGenerator::visitVarDecl(SysYParser::VarDeclContext *ctx) { } } else{ - // 如果值不是常量,我们通常不能确定它是否为零,所以不进行 memset 优化 allValuesAreZero = false; break; } @@ -171,64 +240,51 @@ std::any SysYIRGenerator::visitVarDecl(SysYParser::VarDeclContext *ctx) { } if (allValuesAreZero) { - // 如果所有初始化值都是零(或没有明确初始化但语法允许),使用 memset 优化 builder.createMemsetInst( - alloca, // 目标数组的起始地址 - ConstantInteger::get(0), // 偏移量(通常为0),后续删除 + alloca, + ConstantInteger::get(0), ConstantInteger::get(totalSizeInBytes), - ConstantInteger::get(0)); // 填充的总字节数 + ConstantInteger::get(0)); } else { - // **逐元素存储:遍历所有初始值,并为每个值生成一个 store 指令** for (size_t k = 0; k < counterValues.size(); ++k) { - // 用于存储当前元素的索引列表 std::vector currentIndices; - int tempLinearIndex = k; // 临时线性索引,用于计算多维索引 + 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(tempLinearIndex % dimSizes[dimIdx]))); - // 更新线性索引,用于计算下一个更高维度的索引 tempLinearIndex /= dimSizes[dimIdx]; } - // **生成 store 指令,传入值、基指针和计算出的索引列表** - // 你的 builder.createStoreInst 签名需要能够接受这些参数 - // 假设你的 builder.createStoreInst(Value *val, Value *ptr, const std::vector &indices, ...) - builder.createStoreInst(counterValues[k], alloca, currentIndices); + // 计算元素的地址 + Value* elementAddress = getGEPAddressInst(alloca, currentIndices); + // 生成 store 指令 (假设 createStoreInst 接受 Value* value, Value* pointer) + builder.createStoreInst(counterValues[k], elementAddress); } } } } - else - { // **如果没有显式初始化值,默认对数组进行零初始化** - if (!dims.empty()) - { // 只有数组才需要默认的零初始化 + else { // 如果没有显式初始化值,默认对数组进行零初始化 + if (!dims.empty()) { // 只有数组才需要默认的零初始化 int numElements = 1; - for (Value *dimVal : dims) - { - if (ConstantInteger *constInt = dynamic_cast(dimVal)) - { + for (Value *dimVal : dims) { + if (ConstantInteger *constInt = dynamic_cast(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); @@ -356,29 +412,56 @@ std::any SysYIRGenerator::visitAssignStmt(SysYParser::AssignStmtContext *ctx) { for (const auto &exp : lVal->exp()) { dims.push_back(std::any_cast(visitExp(exp))); } + + auto variable = module->getVariable(name); // 获取 AllocaInst 或 GlobalValue + Value* value = std::any_cast(visitExp(ctx->exp())); // 右值 - auto variable = module->getVariable(name); - Value* value = std::any_cast(visitExp(ctx->exp())); - Type* variableType = dynamic_cast(variable->getType())->getBaseType(); + if (variable == nullptr) { + throw std::runtime_error("Variable " + name + " not found in assignment."); + } - // 左值右值类型不同处理 - if (variableType != value->getType()) { + // 计算最终赋值目标元素的类型 + // variable 本身应该是一个指针类型 (例如 int* 或 int[2][3]*) + if (!variable->getType()->isPointer()) { + assert(false && "Variable to be assigned must be a pointer type!"); + return std::any(); + } + Type* targetElementType = variable->getType()->as()->getBaseType(); // 从基指针指向的类型开始 + + // 模拟 GEP 路径,根据 dims 确定最终元素的类型 + for (size_t i = 0; i < dims.size(); ++i) { + if (targetElementType && targetElementType->isArray()) { + targetElementType = targetElementType->as()->getElementType(); + } else { + break; // 如果不是数组类型但还有索引,或者索引超出维度,则停止推断 + } + } + + // 左值右值类型不同处理:根据最终元素类型进行转换 + if (targetElementType != value->getType()) { ConstantValue * constValue = dynamic_cast(value); if (constValue != nullptr) { - if (variableType == Type::getFloatType()) { - value = ConstantInteger::get(static_cast(constValue->getInt())); - } else { - value = ConstantFloating::get(static_cast(constValue->getFloat())); + if (targetElementType == Type::getFloatType()) { + value = ConstantFloating::get(static_cast(constValue->getInt())); + } else { // 假设如果不是浮点型,就是整型 + value = ConstantInteger::get(static_cast(constValue->getFloat())); } } else { - if (variableType == Type::getFloatType()) { + if (targetElementType == Type::getFloatType()) { value = builder.createIToFInst(value); - } else { + } else { // 假设如果不是浮点型,就是整型 value = builder.createFtoIInst(value); } } } - builder.createStoreInst(value, variable, dims, variable->getName()); + + // 计算目标地址:如果 dims 为空,就是变量本身地址;否则通过 GEP 计算 + Value* targetAddress = variable; + if (!dims.empty()) { + targetAddress = getGEPAddressInst(variable, dims); + } + + builder.createStoreInst(value, targetAddress); return std::any(); } @@ -576,51 +659,89 @@ std::any SysYIRGenerator::visitReturnStmt(SysYParser::ReturnStmtContext *ctx) { } +// SysYIRGenerator.cpp (修改部分) + std::any SysYIRGenerator::visitLValue(SysYParser::LValueContext *ctx) { std::string name = ctx->Ident()->getText(); User* variable = module->getVariable(name); Value* value = nullptr; + if (variable == nullptr) { + throw std::runtime_error("Variable " + name + " not found."); + } std::vector dims; for (const auto &exp : ctx->exp()) { dims.push_back(std::any_cast(visitExp(exp))); } - if (variable == nullptr) { - throw std::runtime_error("Variable " + name + " not found."); - } - - bool indicesConstant = true; - for (const auto &dim : dims) { - if (dynamic_cast(dim) == nullptr) { - indicesConstant = false; - break; - } + // 1. 获取变量的声明维度数量 + unsigned declaredNumDims = 0; + if (AllocaInst* alloc = dynamic_cast(variable)) { + declaredNumDims = alloc->getNumDims(); + } else if (GlobalValue* glob = dynamic_cast(variable)) { + declaredNumDims = glob->getNumDims(); + } else if (ConstantVariable* constV = dynamic_cast(variable)) { + declaredNumDims = constV->getNumDims(); } + // 2. 处理常量变量 (ConstantVariable) 且所有索引都是常量的情况 ConstantVariable* constVar = dynamic_cast(variable); - GlobalValue* globalVar = dynamic_cast(variable); - AllocaInst* localVar = dynamic_cast(variable); - if (constVar != nullptr && indicesConstant) { - // 如果是常量变量,且索引是常量,则直接获取子数组 - value = constVar->getByIndices(dims); - } else if (module->isInGlobalArea() && (globalVar != nullptr)) { - assert(indicesConstant); - value = globalVar->getByIndices(dims); - } else { - if ((globalVar != nullptr && globalVar->getNumDims() > dims.size()) || - (localVar != nullptr && localVar->getNumDims() > dims.size()) || - (constVar != nullptr && constVar->getNumDims() > dims.size())) { - // value = builder.createLaInst(variable, indices); - // 如果变量是全局变量或局部变量,且索引数量小于维度数量,则创建createGetSubArray获取子数组 - auto getArrayInst = - builder.createGetSubArray(dynamic_cast(variable), dims); - value = getArrayInst->getChildArray(); - } else { - value = builder.createLoadInst(variable, dims); + if (constVar != nullptr) { + bool allIndicesConstant = true; + for (const auto &dim : dims) { + if (dynamic_cast(dim) == nullptr) { + allIndicesConstant = false; + break; + } + } + if (allIndicesConstant) { + // 如果是常量变量且所有索引都是常量,直接通过 getByIndices 获取编译时值 + // 这个方法会根据索引深度返回最终的标量值或指向子数组的指针 (作为 ConstantValue/Variable) + return constVar->getByIndices(dims); } } + // 3. 处理可变变量 (AllocaInst/GlobalValue) 或带非常量索引的常量变量 + // 这里区分标量访问和数组元素/子数组访问 + + // 检查是否是访问标量变量本身(没有索引,且声明维度为0) + if (dims.empty() && declaredNumDims == 0) { + // 对于标量变量,直接加载其值。 + // variable 本身就是指向标量的指针 (e.g., int* %a) + if (dynamic_cast(variable) || dynamic_cast(variable)) { + value = builder.createLoadInst(variable); + } else { + // 如果走到这里且不是AllocaInst/GlobalValue,但dims为空且declaredNumDims为0, + // 且又不是ConstantVariable (前面已处理),则可能是错误情况。 + assert(false && "Unhandled scalar variable type in LValue access."); + return static_cast(nullptr); + } + } else { + // 访问数组元素或子数组(有索引,或变量本身是数组/多维指针) + Value* targetAddress = nullptr; + + // GEP 的基指针就是变量本身(它是一个指向内存的指针) + if (dynamic_cast(variable) || dynamic_cast(variable) || (constVar != nullptr)) { + // 允许对 ConstantVariable (如果它代表全局数组常量) 进行 GEP + targetAddress = getGEPAddressInst(variable, dims); + } else { + // 其他情况(例如尝试对非指针类型或不支持的 LValue 进行 GEP)应报错 + assert(false && "LValue variable type not supported for GEP or dynamic load."); + return static_cast(nullptr); + } + + // 现在 targetAddress 持有元素或子数组的地址。 + // 需要判断是加载值,还是返回子数组的地址。 + + // 如果提供的索引数量少于声明的维度数量,则表示访问的是子数组,返回其地址 + if (dims.size() < declaredNumDims) { + value = targetAddress; + } else { + // 否则,表示访问的是最终的标量元素,加载其值 + // 假设 createLoadInst 接受 Value* pointer + value = builder.createLoadInst(targetAddress); + } + } return value; } diff --git a/src/SysYIRPrinter.cpp b/src/SysYIRPrinter.cpp index 7d92a0f..952d500 100644 --- a/src/SysYIRPrinter.cpp +++ b/src/SysYIRPrinter.cpp @@ -3,12 +3,11 @@ #include #include #include -#include "IR.h" +#include "IR.h" // 确保IR.h包含了ArrayType、GetElementPtrInst等的定义 namespace sysy { void SysYPrinter::printIR() { - const auto &functions = pModule->getFunctions(); //TODO: Print target datalayout and triple (minimal required by LLVM) @@ -36,11 +35,18 @@ std::string SysYPrinter::getTypeString(Type *type) { return "i32"; } else if (type->isFloat()) { return "float"; - } else if (auto ptrType = dynamic_cast(type)) { + // 递归打印指针指向的类型,然后加上 '*' return getTypeString(ptrType->getBaseType()) + "*"; - } else if (auto ptrType = dynamic_cast(type)) { - return getTypeString(ptrType->getReturnType()); + } else if (auto funcType = dynamic_cast(type)) { + // 对于函数类型,打印其返回类型 + // 注意:这里可能需要更完整的函数签名打印,取决于你的IR表示方式 + // 比如:`retType (paramType1, paramType2, ...)` + // 但为了简化和LLVM IR兼容性,通常在定义时完整打印 + return getTypeString(funcType->getReturnType()); + } else if (auto arrayType = dynamic_cast(type)) { // 新增:处理数组类型 + // 打印格式为 [num_elements x element_type] + return "[" + std::to_string(arrayType->getNumElements()) + " x " + getTypeString(arrayType->getElementType()) + "]"; } assert(false && "Unsupported type"); return ""; @@ -51,15 +57,23 @@ std::string SysYPrinter::getValueName(Value *value) { return "@" + global->getName(); } else if (auto inst = dynamic_cast(value)) { return "%" + inst->getName(); - } else if (auto constVal = dynamic_cast(value)) { - if (constVal->isFloat()) { - return std::to_string(constVal->getFloat()); + } else if (auto constInt = dynamic_cast(value)) { // 优先匹配具体的常量类型 + return std::to_string(constInt->getInt()); + } else if (auto constFloat = dynamic_cast(value)) { // 优先匹配具体的常量类型 + return std::to_string(constFloat->getFloat()); + } else if (auto constUndef = dynamic_cast(value)) { // 如果有Undef类型 + return "undef"; + } else if (auto constVal = dynamic_cast(value)) { // fallback for generic ConstantValue + // 这里的逻辑可能需要根据你ConstantValue的实际设计调整 + // 确保它能处理所有可能的ConstantValue + if (constVal->getType()->isFloat()) { + return std::to_string(constVal->getFloat()); } return std::to_string(constVal->getInt()); } else if (auto constVar = dynamic_cast(value)) { - return constVar->getName(); + return constVar->getName(); // 假设ConstantVariable有自己的名字或通过getByIndices获取值 } - assert(false && "Unknown value type"); + assert(false && "Unknown value type or unable to get value name"); return ""; } @@ -77,44 +91,35 @@ void SysYPrinter::printGlobalVariable() { for (const auto &global : globals) { std::cout << "@" << global->getName() << " = global "; - auto baseType = dynamic_cast(global->getType())->getBaseType(); - printType(baseType); - - if (global->getNumDims() > 0) { - // Array type - std::cout << " ["; - for (unsigned i = 0; i < global->getNumDims(); i++) { - if (i > 0) std::cout << " x "; - std::cout << getValueName(global->getDim(i)); - } - std::cout << "]"; - } + // 全局变量的类型是一个指针,指向其基类型 (可能是 ArrayType 或 Integer/FloatType) + auto globalVarBaseType = dynamic_cast(global->getType())->getBaseType(); + printType(globalVarBaseType); // 打印全局变量的实际类型 (例如 i32 或 [10 x i32]) std::cout << " "; - if (global->getNumDims() > 0) { - // Array initializer - std::cout << "["; - auto values = global->getInitValues(); - auto counterValues = values.getValues(); - auto counterNumbers = values.getNumbers(); + // 检查是否是数组类型 (通过检查 globalVarBaseType 是否是 ArrayType) + if (globalVarBaseType->isArray()) { + // 数组初始化器 + std::cout << "["; // LLVM IR 数组初始化器格式: [type value, type value, ...] + auto values = global->getInitValues(); // 假设 getInitValues() 返回一个 ValueCounter + const std::vector &counterValues = values.getValues(); // 获取所有值 - for (size_t i = 0; i < counterNumbers.size(); i++) { + for (size_t i = 0; i < counterValues.size(); i++) { if (i > 0) std::cout << ", "; - if (baseType->isFloat()) { - std::cout << "float " << dynamic_cast(counterValues[i])->getFloat(); - } else { - std::cout << "i32 " << dynamic_cast(counterValues[i])->getInt(); - } + // 打印元素类型,这个元素类型应该是数组的最终元素类型,例如 i32 或 float + // 可以从 globalVarBaseType 逐层剥离得到最终元素类型,但这里简化为直接从值获取 + printType(counterValues[i]->getType()); + std::cout << " "; + printValue(counterValues[i]); } std::cout << "]"; } else { - // Scalar initializer - if (baseType->isFloat()) { - std::cout << "float " << dynamic_cast(global->getByIndex(0))->getFloat(); - } else { - std::cout << "i32 " << dynamic_cast(global->getByIndex(0))->getInt(); - } + // 标量初始化器 + // 假设标量全局变量的初始化值通过 getByIndex(0) 获取 + Value* initVal = global->getByIndex(0); + printType(initVal->getType()); // 打印标量值的类型 + std::cout << " "; + printValue(initVal); // 打印标量值 } std::cout << ", align 4" << std::endl; @@ -209,19 +214,19 @@ void SysYPrinter::printInst(Instruction *pInst) { case Kind::kFDiv: std::cout << "fdiv"; break; case Kind::kICmpEQ: std::cout << "icmp eq"; break; case Kind::kICmpNE: std::cout << "icmp ne"; break; - case Kind::kICmpLT: std::cout << "icmp slt"; break; + case Kind::kICmpLT: std::cout << "icmp slt"; break; // LLVM uses slt/sgt for signed less/greater than case Kind::kICmpGT: std::cout << "icmp sgt"; break; case Kind::kICmpLE: std::cout << "icmp sle"; break; case Kind::kICmpGE: std::cout << "icmp sge"; break; - case Kind::kFCmpEQ: std::cout << "fcmp oeq"; break; - case Kind::kFCmpNE: std::cout << "fcmp one"; break; - case Kind::kFCmpLT: std::cout << "fcmp olt"; break; - case Kind::kFCmpGT: std::cout << "fcmp ogt"; break; - case Kind::kFCmpLE: std::cout << "fcmp ole"; break; - case Kind::kFCmpGE: std::cout << "fcmp oge"; break; + case Kind::kFCmpEQ: std::cout << "fcmp oeq"; break; // oeq for ordered equal + case Kind::kFCmpNE: std::cout << "fcmp one"; break; // one for ordered not equal + case Kind::kFCmpLT: std::cout << "fcmp olt"; break; // olt for ordered less than + case Kind::kFCmpGT: std::cout << "fcmp ogt"; break; // ogt for ordered greater than + case Kind::kFCmpLE: std::cout << "fcmp ole"; break; // ole for ordered less than or equal + case Kind::kFCmpGE: std::cout << "fcmp oge"; break; // oge for ordered greater than or equal case Kind::kAnd: std::cout << "and"; break; case Kind::kOr: std::cout << "or"; break; - default: break; + default: break; // Should not reach here } // Types and operands @@ -238,7 +243,6 @@ void SysYPrinter::printInst(Instruction *pInst) { case Kind::kNeg: case Kind::kNot: case Kind::kFNeg: - case Kind::kFNot: case Kind::kFtoI: case Kind::kBitFtoI: case Kind::kItoF: @@ -250,31 +254,39 @@ void SysYPrinter::printInst(Instruction *pInst) { } switch (pInst->getKind()) { - case Kind::kNeg: std::cout << "sub "; break; - case Kind::kNot: std::cout << "not "; break; - case Kind::kFNeg: std::cout << "fneg "; break; - case Kind::kFNot: std::cout << "fneg "; break; // FNot not standard, map to fneg - case Kind::kFtoI: std::cout << "fptosi "; break; - case Kind::kBitFtoI: std::cout << "bitcast "; break; - case Kind::kItoF: std::cout << "sitofp "; break; - case Kind::kBitItoF: std::cout << "bitcast "; break; - default: break; + case Kind::kNeg: std::cout << "sub "; break; // integer negation is `sub i32 0, operand` + case Kind::kNot: std::cout << "xor "; break; // logical/bitwise NOT is `xor i32 -1, operand` or `xor i1 true, operand` + case Kind::kFNeg: std::cout << "fneg "; break; // float negation + case Kind::kFtoI: std::cout << "fptosi "; break; // float to signed integer + case Kind::kBitFtoI: std::cout << "bitcast "; break; // bitcast float to int + case Kind::kItoF: std::cout << "sitofp "; break; // signed integer to float + case Kind::kBitItoF: std::cout << "bitcast "; break; // bitcast int to float + default: break; // Should not reach here } - printType(unyInst->getType()); + printType(unyInst->getOperand()->getType()); // Print operand type std::cout << " "; - // Special handling for negation - if (pInst->getKind() == Kind::kNeg || pInst->getKind() == Kind::kNot) { - std::cout << "i32 0, "; + // Special handling for integer negation and logical NOT + if (pInst->getKind() == Kind::kNeg) { + std::cout << "0, "; // for 'sub i32 0, operand' + } else if (pInst->getKind() == Kind::kNot) { + // For logical NOT (i1 -> i1), use 'xor i1 true, operand' + // For bitwise NOT (i32 -> i32), use 'xor i32 -1, operand' + if (unyInst->getOperand()->getType()->isInt()) { // Assuming i32 for bitwise NOT + std::cout << "NOT, "; // or specific bitmask for NOT + } else { // Assuming i1 for logical NOT + std::cout << "true, "; + } } printValue(pInst->getOperand(0)); - // For bitcast, need to specify destination type - if (pInst->getKind() == Kind::kBitFtoI || pInst->getKind() == Kind::kBitItoF) { + // For type conversions (fptosi, sitofp, bitcast), need to specify destination type + if (pInst->getKind() == Kind::kFtoI || pInst->getKind() == Kind::kItoF || + pInst->getKind() == Kind::kBitFtoI || pInst->getKind() == Kind::kBitItoF) { std::cout << " to "; - printType(unyInst->getType()); + printType(unyInst->getType()); // Print result type } std::cout << std::endl; @@ -289,7 +301,7 @@ void SysYPrinter::printInst(Instruction *pInst) { } std::cout << "call "; - printType(callInst->getType()); + printType(callInst->getType()); // Return type of the call std::cout << " @" << function->getName() << "("; auto params = callInst->getArguments(); @@ -297,9 +309,9 @@ void SysYPrinter::printInst(Instruction *pInst) { for (auto ¶m : params) { if (!first) std::cout << ", "; first = false; - printType(param->getValue()->getType()); + printType(param->getValue()->getType()); // Type of argument std::cout << " "; - printValue(param->getValue()); + printValue(param->getValue()); // Value of argument } std::cout << ")" << std::endl; @@ -307,7 +319,7 @@ void SysYPrinter::printInst(Instruction *pInst) { case Kind::kCondBr: { auto condBrInst = dynamic_cast(pInst); - std::cout << "br i1 "; + std::cout << "br i1 "; // Condition type should be i1 printValue(condBrInst->getCondition()); std::cout << ", label %" << condBrInst->getThenBlock()->getName(); std::cout << ", label %" << condBrInst->getElseBlock()->getName(); @@ -337,14 +349,17 @@ void SysYPrinter::printInst(Instruction *pInst) { auto allocaInst = dynamic_cast(pInst); std::cout << "%" << allocaInst->getName() << " = alloca "; - auto baseType = dynamic_cast(allocaInst->getType())->getBaseType(); - printType(baseType); + // AllocaInst 的类型现在应该是一个 PointerType,指向正确的 ArrayType 或 ScalarType + // 例如:alloca i32, align 4 或者 alloca [10 x i32], align 4 + auto allocatedType = dynamic_cast(allocaInst->getType())->getBaseType(); + printType(allocatedType); - if (allocaInst->getNumDims() > 0) { + // 仍然打印维度信息,如果存在的话 + if (allocaInst->getNumDims() > 0) { std::cout << ", "; for (size_t i = 0; i < allocaInst->getNumDims(); i++) { if (i > 0) std::cout << ", "; - printType(Type::getIntType()); + printType(Type::getIntType()); // 维度大小通常是 i32 类型 std::cout << " "; printValue(allocaInst->getDim(i)); } @@ -356,70 +371,74 @@ void SysYPrinter::printInst(Instruction *pInst) { case Kind::kLoad: { auto loadInst = dynamic_cast(pInst); std::cout << "%" << loadInst->getName() << " = load "; - printType(loadInst->getType()); + printType(loadInst->getType()); // 加载的结果类型 std::cout << ", "; - printType(loadInst->getPointer()->getType()); + printType(loadInst->getPointer()->getType()); // 指针类型 std::cout << " "; - printValue(loadInst->getPointer()); + printValue(loadInst->getPointer()); // 要加载的地址 + // 仍然打印索引信息,如果存在的话 if (loadInst->getNumIndices() > 0) { - std::cout << ", "; + std::cout << ", indices "; // 或者其他分隔符,取决于你期望的格式 for (size_t i = 0; i < loadInst->getNumIndices(); i++) { - if (i > 0) std::cout << ", "; - printType(Type::getIntType()); - std::cout << " "; - printValue(loadInst->getIndex(i)); + if (i > 0) std::cout << ", "; + printType(loadInst->getIndex(i)->getType()); + std::cout << " "; + printValue(loadInst->getIndex(i)); } } std::cout << ", align 4" << std::endl; } break; - case Kind::kLa: { - auto laInst = dynamic_cast(pInst); - std::cout << "%" << laInst->getName() << " = getelementptr inbounds "; - - auto ptrType = dynamic_cast(laInst->getPointer()->getType()); - printType(ptrType->getBaseType()); - std::cout << ", "; - printType(laInst->getPointer()->getType()); - std::cout << " "; - printValue(laInst->getPointer()); - std::cout << ", "; - - for (size_t i = 0; i < laInst->getNumIndices(); i++) { - if (i > 0) std::cout << ", "; - printType(Type::getIntType()); - std::cout << " "; - printValue(laInst->getIndex(i)); - } - - std::cout << std::endl; - } break; - case Kind::kStore: { auto storeInst = dynamic_cast(pInst); std::cout << "store "; - printType(storeInst->getValue()->getType()); + printType(storeInst->getValue()->getType()); // 要存储的值的类型 std::cout << " "; - printValue(storeInst->getValue()); + printValue(storeInst->getValue()); // 要存储的值 std::cout << ", "; - printType(storeInst->getPointer()->getType()); + printType(storeInst->getPointer()->getType()); // 目标指针的类型 std::cout << " "; - printValue(storeInst->getPointer()); + printValue(storeInst->getPointer()); // 目标地址 + // 仍然打印索引信息,如果存在的话 if (storeInst->getNumIndices() > 0) { - std::cout << ", "; + std::cout << ", indices "; // 或者其他分隔符 for (size_t i = 0; i < storeInst->getNumIndices(); i++) { - if (i > 0) std::cout << ", "; - printType(Type::getIntType()); - std::cout << " "; - printValue(storeInst->getIndex(i)); + if (i > 0) std::cout << ", "; + printType(storeInst->getIndex(i)->getType()); + std::cout << " "; + printValue(storeInst->getIndex(i)); } } std::cout << ", align 4" << std::endl; } break; + + case Kind::kGetElementPtr: { // 新增:GetElementPtrInst 打印 + auto gepInst = dynamic_cast(pInst); + std::cout << "%" << gepInst->getName() << " = getelementptr inbounds "; // 假设总是 inbounds + + // GEP 的第一个操作数是基指针,其类型是一个指向聚合类型的指针 + // 第一个参数是基指针所指向的聚合类型的类型 (e.g., [10 x i32]) + auto basePtrType = dynamic_cast(gepInst->getBasePointer()->getType()); + printType(basePtrType->getBaseType()); // 打印基指针指向的类型 + + std::cout << ", "; + printType(gepInst->getBasePointer()->getType()); // 打印基指针自身的类型 (e.g., [10 x i32]*) + std::cout << " "; + printValue(gepInst->getBasePointer()); // 打印基指针 + + // 打印所有索引 + for (auto indexVal : gepInst->getIndices()) { // 使用 getIndices() 迭代器 + std::cout << ", "; + printType(indexVal->getValue()->getType()); // 打印索引的类型 (通常是 i32) + std::cout << " "; + printValue(indexVal->getValue()); // 打印索引值 + } + std::cout << std::endl; + } break; case Kind::kMemset: { auto memsetInst = dynamic_cast(pInst); @@ -433,51 +452,40 @@ void SysYPrinter::printInst(Instruction *pInst) { printValue(memsetInst->getValue()); std::cout << ", i32 "; printValue(memsetInst->getSize()); - std::cout << ", i1 false)" << std::endl; + std::cout << ", i1 false)" << std::endl; // alignment for memset is typically i1 } break; case Kind::kPhi: { auto phiInst = dynamic_cast(pInst); - printValue(phiInst->getOperand(0)); - std::cout << " = phi "; - printType(phiInst->getType()); + // Phi 指令的名称通常是结果变量 + std::cout << "%" << phiInst->getName() << " = phi "; + printType(phiInst->getType()); // Phi 结果类型 - for (unsigned i = 1; i < phiInst->getNumOperands(); i++) { - if (i > 0) std::cout << ", "; + // Phi 指令的操作数是成对的 [value, basic_block] + // 这里假设 getOperands() 返回的是 (val1, block1, val2, block2...) + // 如果你的 PhiInst 存储方式是 getIncomingValues() 和 getIncomingBlocks(),请相应调整 + // LLVM IR 格式: phi type [value1, block1], [value2, block2] + bool firstPair = true; + for (unsigned i = 0; i < phiInst->getNumOperands() / 2; ++i) { // 遍历成对的操作数 + if (!firstPair) std::cout << ", "; + firstPair = false; std::cout << "[ "; - printValue(phiInst->getOperand(i)); + printValue(phiInst->getOperand(i * 2)); // value + std::cout << ", %"; + printValue(phiInst->getOperand(i * 2 + 1)); // block std::cout << " ]"; } std::cout << std::endl; } break; - case Kind::kGetSubArray: { - auto getSubArrayInst = dynamic_cast(pInst); - std::cout << "%" << getSubArrayInst->getName() << " = getelementptr inbounds "; - - auto ptrType = dynamic_cast(getSubArrayInst->getFatherArray()->getType()); - printType(ptrType->getBaseType()); - std::cout << ", "; - printType(getSubArrayInst->getFatherArray()->getType()); - std::cout << " "; - printValue(getSubArrayInst->getFatherArray()); - std::cout << ", "; - bool firstIndex = true; - for (auto &index : getSubArrayInst->getIndices()) { - if (!firstIndex) std::cout << ", "; - firstIndex = false; - printType(Type::getIntType()); - std::cout << " "; - printValue(index->getValue()); - } - - std::cout << std::endl; - } break; + // 以下两个 Kind 应该删除或替换为 kGEP + // case Kind::kLa: { /* REMOVED */ } break; + // case Kind::kGetSubArray: { /* REMOVED */ } break; default: - assert(false && "Unsupported instruction kind"); + assert(false && "Unsupported instruction kind in SysYPrinter"); break; } } -} // namespace sysy +} // namespace sysy \ No newline at end of file diff --git a/src/include/IR.h b/src/include/IR.h index 060bdc5..6e35715 100644 --- a/src/include/IR.h +++ b/src/include/IR.h @@ -49,6 +49,7 @@ class Type { kLabel, kPointer, kFunction, + kArray, }; Kind kind; ///< 表示具体类型的变量 @@ -65,6 +66,7 @@ class Type { static Type* getPointerType(Type *baseType); ///< 返回表示指向baseType类型的Pointer类型的Type指针 static Type* getFunctionType(Type *returnType, const std::vector ¶mTypes = {}); ///< 返回表示返回类型为returnType,形参类型列表为paramTypes的函数类型的Type指针 + static Type* getArrayType(Type *elementType, unsigned numElements); public: Kind getKind() const { return kind; } ///< 返回Type对象代表原始标量类型 @@ -74,6 +76,7 @@ class Type { bool isLabel() const { return kind == kLabel; } ///< 判定是否为Label类型 bool isPointer() const { return kind == kPointer; } ///< 判定是否为Pointer类型 bool isFunction() const { return kind == kFunction; } ///< 判定是否为Function类型 + bool isArray() const { return kind == Kind::kArray; } unsigned getSize() const; ///< 返回类型所占的空间大小(字节) /// 尝试将一个变量转换为给定的Type及其派生类类型的变量 template @@ -115,6 +118,22 @@ class FunctionType : public Type { unsigned getNumParams() const { return paramTypes.size(); } ///< 获取形参数量 }; +class ArrayType : public Type { + public: + // elements:数组的元素类型 (例如,int[3] 的 elementType 是 int) + // numElements:该维度的大小 (例如,int[3] 的 numElements 是 3) + static ArrayType *get(Type *elementType, unsigned numElements); + + Type *getElementType() const { return elementType; } + unsigned getNumElements() const { return numElements; } + + protected: + ArrayType(Type *elementType, unsigned numElements) + : Type(Kind::kArray), elementType(elementType), numElements(numElements) {} + Type *elementType; + unsigned numElements; // 当前维度的大小 +}; + /*! * @} */ @@ -602,49 +621,6 @@ class User : public Value { void setOperand(unsigned index, Value *value); ///< 设置操作数 }; -class GetSubArrayInst; -/** - * 左值 具有地址的对象 - */ -class LVal { - friend class GetSubArrayInst; - - protected: - LVal *fatherLVal{}; ///< 父左值 - std::list> childrenLVals; ///< 子左值 - GetSubArrayInst *defineInst{}; /// 定义该左值的GetSubArray指令 - - protected: - LVal() = default; - - public: - virtual ~LVal() = default; - virtual std::vector getLValDims() const = 0; ///< 获取左值的维度 - virtual unsigned getLValNumDims() const = 0; ///< 获取左值的维度数量 - - public: - LVal* getFatherLVal() const { return fatherLVal; } ///< 获取父左值 - const std::list>& getChildrenLVals() const { - return childrenLVals; - } ///< 获取子左值列表 - LVal* getAncestorLVal() const { - auto curLVal = const_cast(this); - while (curLVal->getFatherLVal() != nullptr) { - curLVal = curLVal->getFatherLVal(); - } - return curLVal; - } ///< 获取祖先左值 - void setFatherLVal(LVal *father) { fatherLVal = father; } ///< 设置父左值 - void setDefineInst(GetSubArrayInst *inst) { defineInst = inst; } ///< 设置定义指令 - void addChild(LVal *child) { childrenLVals.emplace_back(child); } ///< 添加子左值 - void removeChild(LVal *child) { - auto iter = std::find_if(childrenLVals.begin(), childrenLVals.end(), - [child](const std::unique_ptr &ptr) { return ptr.get() == child; }); - childrenLVals.erase(iter); - } ///< 移除子左值 - GetSubArrayInst* getDefineInst() const { return defineInst; } ///< 获取定义指令 -}; - /*! * Base of all concrete instruction types. */ @@ -694,15 +670,15 @@ class Instruction : public User { kAlloca = 0x1UL << 33, kLoad = 0x1UL << 34, kStore = 0x1UL << 35, - kLa = 0x1UL << 36, + kGetElementPtr = 0x1UL << 36, kMemset = 0x1UL << 37, - kGetSubArray = 0x1UL << 38, + // kGetSubArray = 0x1UL << 38, // Constant Kind removed as Constants are now Values, not Instructions. // kConstant = 0x1UL << 37, // Conflicts with kMemset if kept as is // phi kPhi = 0x1UL << 39, kBitItoF = 0x1UL << 40, - kBitFtoI = 0x1UL << 41 + kBitFtoI = 0x1UL << 41, }; protected: @@ -793,14 +769,12 @@ public: return "Load"; case kStore: return "Store"; - case kLa: - return "La"; + case kGetElementPtr: + return "GetElementPtr"; case kMemset: return "Memset"; case kPhi: return "Phi"; - case kGetSubArray: - return "GetSubArray"; default: return "Unknown"; } @@ -853,9 +827,8 @@ public: bool isAlloca() const { return kind == kAlloca; } bool isLoad() const { return kind == kLoad; } bool isStore() const { return kind == kStore; } - bool isLa() const { return kind == kLa; } + bool isGetElementPtr() const { return kind == kGetElementPtr; } bool isMemset() const { return kind == kMemset; } - bool isGetSubArray() const { return kind == kGetSubArray; } bool isCall() const { return kind == kCall; } bool isReturn() const { return kind == kReturn; } bool isDefine() const { @@ -867,26 +840,6 @@ public: class Function; //! Function call. -class LaInst : public Instruction { - friend class Function; - friend class IRBuilder; - - protected: - explicit LaInst(Value *pointer, const std::vector &indices = {}, BasicBlock *parent = nullptr, - const std::string &name = "") - : Instruction(Kind::kLa, pointer->getType(), parent, name) { - assert(pointer); - addOperand(pointer); - addOperands(indices); - } - - public: - unsigned getNumIndices() const { return getNumOperands() - 1; } ///< 获取索引长度 - Value* getPointer() const { return getOperand(0); } ///< 获取目标变量的Value指针 - auto getIndices() const { return make_range(std::next(operand_begin()), operand_end()); } ///< 获取索引列表 - Value* getIndex(unsigned index) const { return getOperand(index + 1); } ///< 获取位置为index的索引分量 -}; - class PhiInst : public Instruction { friend class IRBuilder; friend class Function; @@ -1134,7 +1087,7 @@ public: }; // class CondBrInst //! Allocate memory for stack variables, used for non-global variable declartion -class AllocaInst : public Instruction , public LVal { +class AllocaInst : public Instruction { friend class IRBuilder; friend class Function; protected: @@ -1145,14 +1098,6 @@ protected: } public: - std::vector getLValDims() const override { - std::vector dims; - for (const auto &dim : getOperands()) { - dims.emplace_back(dim->getValue()); - } - return dims; - } ///< 获取作为左值的维度数组 - unsigned getLValNumDims() const override { return getNumOperands(); } int getNumDims() const { return getNumOperands(); } auto getDims() const { return getOperands(); } @@ -1161,37 +1106,40 @@ public: }; // class AllocaInst -class GetSubArrayInst : public Instruction { - friend class IRBuilder; - friend class Function; +class GetElementPtrInst : public Instruction { + friend class IRBuilder; // 如果您有IRBuilder来创建指令,需要friend - public: - GetSubArrayInst(LVal *fatherArray, LVal *childArray, const std::vector &indices, - BasicBlock *parent = nullptr, const std::string &name = "") - : Instruction(Kind::kGetSubArray, Type::getVoidType(), parent, name) { - auto predicate = [childArray](const std::unique_ptr &child) -> bool { return child.get() == childArray; }; - if (std::find_if(fatherArray->childrenLVals.begin(), fatherArray->childrenLVals.end(), predicate) == - fatherArray->childrenLVals.end()) { - fatherArray->childrenLVals.emplace_back(childArray); - } - childArray->fatherLVal = fatherArray; - childArray->defineInst = this; - auto fatherArrayValue = dynamic_cast(fatherArray); - auto childArrayValue = dynamic_cast(childArray); - assert(fatherArrayValue); - assert(childArrayValue); - addOperand(fatherArrayValue); - addOperand(childArrayValue); - addOperands(indices); +protected: + // GEP的构造函数: + // resultType: GEP计算出的地址的类型 (通常是指向目标元素类型的指针) + // basePointer: 基指针 (第一个操作数) + // indices: 索引列表 (后续操作数) + GetElementPtrInst(Value *basePointer, + const std::vector &indices = {}, + BasicBlock *parent = nullptr, const std::string &name = "") + : Instruction(Kind::kGetElementPtr, basePointer->getType(), parent, name) { + assert(basePointer && "GEP base pointer cannot be null!"); + // TODO : 安全检查 + assert(basePointer->getType()->isPointer() ); + addOperand(basePointer); // 第一个操作数是基指针 + addOperands(indices); // 随后的操作数是索引 } - public: - Value* getFatherArray() const { return getOperand(0); } ///< 获取父数组 - Value* getChildArray() const { return getOperand(1); } ///< 获取子数组 - LVal* getFatherLVal() const { return dynamic_cast(getOperand(0)); } ///< 获取父左值 - LVal* getChildLVal() const { return dynamic_cast(getOperand(1)); } ///< 获取子左值 - auto getIndices() const { return make_range(std::next(operand_begin(), 2), operand_end()); } ///< 获取索引 - unsigned getNumIndices() const { return getNumOperands() - 2; } ///< 获取索引数量 +public: + Value* getBasePointer() const { return getOperand(0); } + unsigned getNumIndices() const { return getNumOperands() - 1; } + auto getIndices() const { return make_range(std::next(operand_begin()), operand_end());} + Value* getIndex(unsigned index) const { + assert(index < getNumIndices() && "Index out of bounds for GEP!"); + return getOperand(index + 1); + } + + // 静态工厂方法,用于创建GEP指令 (如果需要外部直接创建而非通过IRBuilder) + static GetElementPtrInst* create(Type *resultType, Value *basePointer, + const std::vector &indices = {}, + BasicBlock *parent = nullptr, const std::string &name = "") { + return new GetElementPtrInst(basePointer, indices, parent, name); + } }; //! Load a value from memory address specified by a pointer value @@ -1215,22 +1163,7 @@ public: return make_range(std::next(operand_begin()), operand_end()); } Value* getIndex(int index) const { return getOperand(index + 1); } - std::list getAncestorIndices() const { - std::list indices; - for (const auto &index : getIndices()) { - indices.emplace_back(index->getValue()); - } - auto curPointer = dynamic_cast(getPointer()); - while (curPointer->getFatherLVal() != nullptr) { - auto inserter = std::next(indices.begin()); - for (const auto &index : curPointer->getDefineInst()->getIndices()) { - indices.insert(inserter, index->getValue()); - } - curPointer = curPointer->getFatherLVal(); - } - - return indices; - } ///< 获取相对于祖先数组的索引列表 + }; // class LoadInst //! Store a value to memory address specified by a pointer value @@ -1256,22 +1189,6 @@ public: return make_range(std::next(operand_begin(), 2), operand_end()); } Value* getIndex(int index) const { return getOperand(index + 2); } - std::list getAncestorIndices() const { - std::list indices; - for (const auto &index : getIndices()) { - indices.emplace_back(index->getValue()); - } - auto curPointer = dynamic_cast(getPointer()); - while (curPointer->getFatherLVal() != nullptr) { - auto inserter = std::next(indices.begin()); - for (const auto &index : curPointer->getDefineInst()->getIndices()) { - indices.insert(inserter, index->getValue()); - } - curPointer = curPointer->getFatherLVal(); - } - - return indices; - } ///< 获取相对于祖先数组的索引列表 }; // class StoreInst @@ -1373,7 +1290,7 @@ protected: }; //! Global value declared at file scope -class GlobalValue : public User, public LVal { +class GlobalValue : public User { friend class Module; protected: @@ -1407,16 +1324,6 @@ protected: } public: - unsigned getLValNumDims() const override { return numDims; } ///< 获取作为左值的维度数量 - std::vector getLValDims() const override { - std::vector dims; - for (const auto &dim : getOperands()) { - dims.emplace_back(dim->getValue()); - } - - return dims; - } ///< 获取作为左值的维度列表 - unsigned getNumDims() const { return numDims; } ///< 获取维度数量 Value* getDim(unsigned index) const { return getOperand(index); } ///< 获取位置为index的维度 auto getDims() const { return getOperands(); } ///< 获取维度列表 @@ -1438,7 +1345,7 @@ public: }; // class GlobalValue -class ConstantVariable : public User, public LVal { +class ConstantVariable : public User { friend class Module; protected: @@ -1457,15 +1364,6 @@ class ConstantVariable : public User, public LVal { } public: - unsigned getLValNumDims() const override { return numDims; } ///< 获取作为左值的维度数量 - std::vector getLValDims() const override { - std::vector dims; - for (const auto &dim : getOperands()) { - dims.emplace_back(dim->getValue()); - } - - return dims; - } ///< 获取作为左值的维度列表 Value* getByIndex(unsigned index) const { return initValues.getValue(index); } ///< 通过一维位置index获取值 Value* getByIndices(const std::vector &indices) const { int index = 0; diff --git a/src/include/IRBuilder.h b/src/include/IRBuilder.h index 6df82e7..03df66a 100644 --- a/src/include/IRBuilder.h +++ b/src/include/IRBuilder.h @@ -280,46 +280,6 @@ class IRBuilder { block->getInstructions().emplace(position, inst); return inst; } ///< 创建load指令 - LaInst * createLaInst(Value *pointer, const std::vector &indices = {}, const std::string &name = "") { - std::string newName; - if (name.empty()) { - std::stringstream ss; - ss << tmpIndex; - newName = ss.str(); - tmpIndex++; - } else { - newName = name; - } - - auto inst = new LaInst(pointer, indices, block, newName); - assert(inst); - block->getInstructions().emplace(position, inst); - return inst; - } ///< 创建la指令 - GetSubArrayInst * createGetSubArray(LVal *fatherArray, const std::vector &indices, const std::string &name = "") { - assert(fatherArray->getLValNumDims() > indices.size()); - std::vector subDims; - auto dims = fatherArray->getLValDims(); - auto iter = std::next(dims.begin(), indices.size()); - while (iter != dims.end()) { - subDims.emplace_back(*iter); - iter++; - } - - std::string childArrayName; - std::stringstream ss; - ss << "A" - << "%" << tmpIndex; - childArrayName = ss.str(); - tmpIndex++; - - auto fatherArrayValue = dynamic_cast(fatherArray); - auto childArray = new AllocaInst(fatherArrayValue->getType(), subDims, block, childArrayName); - auto inst = new GetSubArrayInst(fatherArray, childArray, indices, block, childArrayName); - assert(inst); - block->getInstructions().emplace(position, inst); - return inst; - } ///< 创建获取部分数组指令 MemsetInst * createMemsetInst(Value *pointer, Value *begin, Value *size, Value *value, const std::string &name = "") { auto inst = new MemsetInst(pointer, begin, size, value, block, name); assert(inst); @@ -340,6 +300,24 @@ class IRBuilder { block->getInstructions().emplace(block->begin(), inst); return inst; } ///< 创建Phi指令 + GetElementPtrInst* createGetElementPtrInst(Value *basePointer, + const std::vector &indices = {}, + const std::string &name = "") { + std::string newName; + if (name.empty()) { + std::stringstream ss; + ss << tmpIndex; + newName = ss.str(); + tmpIndex++; + } else { + newName = name; + } + + auto inst = new GetElementPtrInst(basePointer, indices, block, newName); + assert(inst); + block->getInstructions().emplace(position, inst); + return inst; + } }; } // namespace sysy diff --git a/src/include/SysYIRGenerator.h b/src/include/SysYIRGenerator.h index fe309e8..9dfd7c5 100644 --- a/src/include/SysYIRGenerator.h +++ b/src/include/SysYIRGenerator.h @@ -68,6 +68,7 @@ public: Module *get() const { return module.get(); } IRBuilder *getBuilder(){ return &builder; } public: + std::any visitCompUnit(SysYParser::CompUnitContext *ctx) override; std::any visitGlobalConstDecl(SysYParser::GlobalConstDeclContext *ctx) override; @@ -134,6 +135,11 @@ public: // std::any visitConstExp(SysYParser::ConstExpContext *ctx) override; +public: + // 获取GEP指令的地址 + Value* getGEPAddressInst(Value* basePointer, const std::vector& indices); + // 构建数组类型 + Type* buildArrayType(Type* baseType, const std::vector& dims); }; // class SysYIRGenerator diff --git a/src/sysyc.cpp b/src/sysyc.cpp index 4fdc7cc..1afe7c9 100644 --- a/src/sysyc.cpp +++ b/src/sysyc.cpp @@ -15,7 +15,7 @@ using namespace antlr4; #include "SysYIRPrinter.h" #include "SysYIRCFGOpt.h" #include "RISCv64Backend.h" -#include "SysYIRAnalyser.h" +// #include "SysYIRAnalyser.h" // #include "DeadCodeElimination.h" #include "AddressCalculationExpansion.h" // #include "Mem2Reg.h" @@ -135,10 +135,10 @@ int main(int argc, char **argv) { SysYCFGOpt cfgopt(moduleIR, builder); cfgopt.SysYOptimizateAfterIR(); - ControlFlowAnalysis cfa(moduleIR); - cfa.init(); - ActiveVarAnalysis ava; - ava.init(moduleIR); + // ControlFlowAnalysis cfa(moduleIR); + // cfa.init(); + // ActiveVarAnalysis ava; + // ava.init(moduleIR); if (DEBUG) { cout << "=== After CFA & AVA (Default) ===\n";