deploy-20250820-3 #1

Merged
gh0s7 merged 352 commits from deploy-20250820-3 into master 2025-08-20 21:20:33 +08:00
8 changed files with 455 additions and 467 deletions
Showing only changes of commit de696b2b53 - Show all commits

View File

@@ -22,7 +22,7 @@ add_executable(sysyc
SysYIRGenerator.cpp
SysYIRPrinter.cpp
SysYIRCFGOpt.cpp
SysYIRAnalyser.cpp
# SysYIRAnalyser.cpp
# DeadCodeElimination.cpp
AddressCalculationExpansion.cpp
# Mem2Reg.cpp

View File

@@ -49,6 +49,11 @@ auto Type::getFunctionType(Type *returnType, const std::vector<Type *> &paramTyp
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<const ArrayType*>(this);
return arrType->getElementType()->getSize() * arrType->getNumElements();
}
case kVoid:
return 0;
}
@@ -95,6 +104,11 @@ FunctionType*FunctionType::get(Type *returnType, const std::vector<Type *> &para
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<LaInst *>(inst);
auto oldPointer = oldLaInst->getPointer();
Value *newPointer;
std::vector<Value *> 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<GetSubArrayInst *>(inst);
auto oldFather = oldGetSubArrayInst->getFatherArray();
auto oldChild = oldGetSubArrayInst->getChildArray();
Value *newFather;
Value *newChild;
std::vector<Value *> 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<LVal *>(newFather), dynamic_cast<LVal *>(newChild), newIndices,
oldNewBlockMap.at(oldGetSubArrayInst->getParent()), ss.str());
ss.str("");
oldNewValueMap.emplace(oldGetSubArrayInst, newGetSubArrayInst);
break;
}
// TODO复制GEP指令
case Instruction::kMemset: {
auto oldMemsetInst = dynamic_cast<MemsetInst *>(inst);

View File

@@ -15,6 +15,73 @@
using namespace std;
namespace sysy {
Type* SysYIRGenerator::buildArrayType(Type* baseType, const std::vector<Value*>& 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<ConstantInteger*>(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<Value*>& 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<PointerType>()->getBaseType();
std::vector<Value*> 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<ArrayType>()->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<Value*>& 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<ArrayValueTree *>(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<sysy::Value *> &counterValues = values.getValues();
// 计算数组的**总元素数量**和**总字节大小**
int numElements = 1;
// 存储每个维度的实际整数大小,用于索引计算
std::vector<int> dimSizes;
for (Value *dimVal : dims) {
if (ConstantInteger *constInt = dynamic_cast<ConstantInteger *>(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<Value *> 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<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);
// 计算元素的地址
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<ConstantInteger *>(dimVal))
{
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);
@@ -356,29 +412,56 @@ std::any SysYIRGenerator::visitAssignStmt(SysYParser::AssignStmtContext *ctx) {
for (const auto &exp : lVal->exp()) {
dims.push_back(std::any_cast<Value *>(visitExp(exp)));
}
auto variable = module->getVariable(name); // 获取 AllocaInst 或 GlobalValue
Value* value = std::any_cast<Value *>(visitExp(ctx->exp())); // 右值
auto variable = module->getVariable(name);
Value* value = std::any_cast<Value *>(visitExp(ctx->exp()));
Type* variableType = dynamic_cast<PointerType *>(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<PointerType>()->getBaseType(); // 从基指针指向的类型开始
// 模拟 GEP 路径,根据 dims 确定最终元素的类型
for (size_t i = 0; i < dims.size(); ++i) {
if (targetElementType && targetElementType->isArray()) {
targetElementType = targetElementType->as<ArrayType>()->getElementType();
} else {
break; // 如果不是数组类型但还有索引,或者索引超出维度,则停止推断
}
}
// 左值右值类型不同处理:根据最终元素类型进行转换
if (targetElementType != value->getType()) {
ConstantValue * constValue = dynamic_cast<ConstantValue *>(value);
if (constValue != nullptr) {
if (variableType == Type::getFloatType()) {
value = ConstantInteger::get(static_cast<float>(constValue->getInt()));
} else {
value = ConstantFloating::get(static_cast<int>(constValue->getFloat()));
if (targetElementType == Type::getFloatType()) {
value = ConstantFloating::get(static_cast<float>(constValue->getInt()));
} else { // 假设如果不是浮点型,就是整型
value = ConstantInteger::get(static_cast<int>(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<Value *> dims;
for (const auto &exp : ctx->exp()) {
dims.push_back(std::any_cast<Value *>(visitExp(exp)));
}
if (variable == nullptr) {
throw std::runtime_error("Variable " + name + " not found.");
}
bool indicesConstant = true;
for (const auto &dim : dims) {
if (dynamic_cast<ConstantValue *>(dim) == nullptr) {
indicesConstant = false;
break;
}
// 1. 获取变量的声明维度数量
unsigned declaredNumDims = 0;
if (AllocaInst* alloc = dynamic_cast<AllocaInst*>(variable)) {
declaredNumDims = alloc->getNumDims();
} else if (GlobalValue* glob = dynamic_cast<GlobalValue*>(variable)) {
declaredNumDims = glob->getNumDims();
} else if (ConstantVariable* constV = dynamic_cast<ConstantVariable*>(variable)) {
declaredNumDims = constV->getNumDims();
}
// 2. 处理常量变量 (ConstantVariable) 且所有索引都是常量的情况
ConstantVariable* constVar = dynamic_cast<ConstantVariable *>(variable);
GlobalValue* globalVar = dynamic_cast<GlobalValue *>(variable);
AllocaInst* localVar = dynamic_cast<AllocaInst *>(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<LVal *>(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<ConstantValue *>(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<AllocaInst*>(variable) || dynamic_cast<GlobalValue*>(variable)) {
value = builder.createLoadInst(variable);
} else {
// 如果走到这里且不是AllocaInst/GlobalValue但dims为空且declaredNumDims为0
// 且又不是ConstantVariable (前面已处理),则可能是错误情况。
assert(false && "Unhandled scalar variable type in LValue access.");
return static_cast<Value*>(nullptr);
}
} else {
// 访问数组元素或子数组(有索引,或变量本身是数组/多维指针)
Value* targetAddress = nullptr;
// GEP 的基指针就是变量本身(它是一个指向内存的指针)
if (dynamic_cast<AllocaInst*>(variable) || dynamic_cast<GlobalValue*>(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<Value*>(nullptr);
}
// 现在 targetAddress 持有元素或子数组的地址。
// 需要判断是加载值,还是返回子数组的地址。
// 如果提供的索引数量少于声明的维度数量,则表示访问的是子数组,返回其地址
if (dims.size() < declaredNumDims) {
value = targetAddress;
} else {
// 否则,表示访问的是最终的标量元素,加载其值
// 假设 createLoadInst 接受 Value* pointer
value = builder.createLoadInst(targetAddress);
}
}
return value;
}

View File

@@ -3,12 +3,11 @@
#include <fstream>
#include <iostream>
#include <string>
#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<PointerType*>(type)) {
// 递归打印指针指向的类型,然后加上 '*'
return getTypeString(ptrType->getBaseType()) + "*";
} else if (auto ptrType = dynamic_cast<FunctionType*>(type)) {
return getTypeString(ptrType->getReturnType());
} else if (auto funcType = dynamic_cast<FunctionType*>(type)) {
// 对于函数类型,打印其返回类型
// 注意这里可能需要更完整的函数签名打印取决于你的IR表示方式
// 比如:`retType (paramType1, paramType2, ...)`
// 但为了简化和LLVM IR兼容性通常在定义时完整打印
return getTypeString(funcType->getReturnType());
} else if (auto arrayType = dynamic_cast<ArrayType*>(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<Instruction*>(value)) {
return "%" + inst->getName();
} else if (auto constVal = dynamic_cast<ConstantValue*>(value)) {
if (constVal->isFloat()) {
return std::to_string(constVal->getFloat());
} else if (auto constInt = dynamic_cast<ConstantInteger*>(value)) { // 优先匹配具体的常量类型
return std::to_string(constInt->getInt());
} else if (auto constFloat = dynamic_cast<ConstantFloating*>(value)) { // 优先匹配具体的常量类型
return std::to_string(constFloat->getFloat());
} else if (auto constUndef = dynamic_cast<UndefinedValue*>(value)) { // 如果有Undef类型
return "undef";
} else if (auto constVal = dynamic_cast<ConstantValue*>(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<ConstantVariable*>(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<PointerType *>(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<PointerType *>(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<sysy::Value *> &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<ConstantValue*>(counterValues[i])->getFloat();
} else {
std::cout << "i32 " << dynamic_cast<ConstantValue*>(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<ConstantValue*>(global->getByIndex(0))->getFloat();
} else {
std::cout << "i32 " << dynamic_cast<ConstantValue*>(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 &param : 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<CondBrInst *>(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<AllocaInst *>(pInst);
std::cout << "%" << allocaInst->getName() << " = alloca ";
auto baseType = dynamic_cast<PointerType *>(allocaInst->getType())->getBaseType();
printType(baseType);
// AllocaInst 的类型现在应该是一个 PointerType指向正确的 ArrayType 或 ScalarType
// 例如alloca i32, align 4 或者 alloca [10 x i32], align 4
auto allocatedType = dynamic_cast<PointerType *>(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<LoadInst *>(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<LaInst *>(pInst);
std::cout << "%" << laInst->getName() << " = getelementptr inbounds ";
auto ptrType = dynamic_cast<PointerType*>(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<StoreInst *>(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<GetElementPtrInst*>(pInst);
std::cout << "%" << gepInst->getName() << " = getelementptr inbounds "; // 假设总是 inbounds
// GEP 的第一个操作数是基指针,其类型是一个指向聚合类型的指针
// 第一个参数是基指针所指向的聚合类型的类型 (e.g., [10 x i32])
auto basePtrType = dynamic_cast<PointerType*>(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<MemsetInst *>(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<PhiInst *>(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<GetSubArrayInst *>(pInst);
std::cout << "%" << getSubArrayInst->getName() << " = getelementptr inbounds ";
auto ptrType = dynamic_cast<PointerType*>(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

View File

@@ -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<Type *> &paramTypes = {});
///< 返回表示返回类型为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 <typename T>
@@ -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<std::unique_ptr<LVal>> childrenLVals; ///< 子左值
GetSubArrayInst *defineInst{}; /// 定义该左值的GetSubArray指令
protected:
LVal() = default;
public:
virtual ~LVal() = default;
virtual std::vector<Value *> getLValDims() const = 0; ///< 获取左值的维度
virtual unsigned getLValNumDims() const = 0; ///< 获取左值的维度数量
public:
LVal* getFatherLVal() const { return fatherLVal; } ///< 获取父左值
const std::list<std::unique_ptr<LVal>>& getChildrenLVals() const {
return childrenLVals;
} ///< 获取子左值列表
LVal* getAncestorLVal() const {
auto curLVal = const_cast<LVal *>(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<LVal> &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<Value *> &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<Value *> getLValDims() const override {
std::vector<Value *> 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<Value *> &indices,
BasicBlock *parent = nullptr, const std::string &name = "")
: Instruction(Kind::kGetSubArray, Type::getVoidType(), parent, name) {
auto predicate = [childArray](const std::unique_ptr<LVal> &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<Value *>(fatherArray);
auto childArrayValue = dynamic_cast<Value *>(childArray);
assert(fatherArrayValue);
assert(childArrayValue);
addOperand(fatherArrayValue);
addOperand(childArrayValue);
addOperands(indices);
protected:
// GEP的构造函数
// resultType: GEP计算出的地址的类型 (通常是指向目标元素类型的指针)
// basePointer: 基指针 (第一个操作数)
// indices: 索引列表 (后续操作数)
GetElementPtrInst(Value *basePointer,
const std::vector<Value *> &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<LVal *>(getOperand(0)); } ///< 获取父左值
LVal* getChildLVal() const { return dynamic_cast<LVal *>(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<Value *> &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<Value *> getAncestorIndices() const {
std::list<Value *> indices;
for (const auto &index : getIndices()) {
indices.emplace_back(index->getValue());
}
auto curPointer = dynamic_cast<LVal *>(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<Value *> getAncestorIndices() const {
std::list<Value *> indices;
for (const auto &index : getIndices()) {
indices.emplace_back(index->getValue());
}
auto curPointer = dynamic_cast<LVal *>(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<Value *> getLValDims() const override {
std::vector<Value *> 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<Value *> getLValDims() const override {
std::vector<Value *> 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<Value *> &indices) const {
int index = 0;

View File

@@ -280,46 +280,6 @@ class IRBuilder {
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建load指令
LaInst * createLaInst(Value *pointer, const std::vector<Value *> &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<Value *> &indices, const std::string &name = "") {
assert(fatherArray->getLValNumDims() > indices.size());
std::vector<Value *> 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<Value *>(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<Value *> &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

View File

@@ -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<Value*>& indices);
// 构建数组类型
Type* buildArrayType(Type* baseType, const std::vector<Value*>& dims);
}; // class SysYIRGenerator

View File

@@ -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";