[midend]修改全局变量,全局常量类,提供维度访问方法,消除维度信息(记录在Type中),createItoFInst命名修复,增加打印全局常量。
This commit is contained in:
@@ -1351,7 +1351,7 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
//! Global value declared at file scope
|
//! Global value declared at file scope
|
||||||
class GlobalValue : public User {
|
class GlobalValue : public Value {
|
||||||
friend class Module;
|
friend class Module;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -1363,9 +1363,10 @@ protected:
|
|||||||
GlobalValue(Module *parent, Type *type, const std::string &name,
|
GlobalValue(Module *parent, Type *type, const std::string &name,
|
||||||
const std::vector<Value *> &dims = {},
|
const std::vector<Value *> &dims = {},
|
||||||
ValueCounter init = {})
|
ValueCounter init = {})
|
||||||
: User(type, name), parent(parent) {
|
: Value(type, name), parent(parent) {
|
||||||
assert(type->isPointer());
|
assert(type->isPointer());
|
||||||
addOperands(dims);
|
// addOperands(dims);
|
||||||
|
// 维度信息已经被记录到Type中,dim只是为了方便初始化
|
||||||
numDims = dims.size();
|
numDims = dims.size();
|
||||||
if (init.size() == 0) {
|
if (init.size() == 0) {
|
||||||
unsigned num = 1;
|
unsigned num = 1;
|
||||||
@@ -1385,20 +1386,34 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
unsigned getNumDims() const { return numDims; } ///< 获取维度数量
|
// unsigned getNumDims() const { return numDims; } ///< 获取维度数量
|
||||||
Value* getDim(unsigned index) const { return getOperand(index); } ///< 获取位置为index的维度
|
// Value* getDim(unsigned index) const { return getOperand(index); } ///< 获取位置为index的维度
|
||||||
auto getDims() const { return getOperands(); } ///< 获取维度列表
|
// auto getDims() const { return getOperands(); } ///< 获取维度列表
|
||||||
|
unsigned getNumIndices() const {
|
||||||
|
return numDims;
|
||||||
|
} ///< 获取维度数量
|
||||||
|
unsigned getIndex(unsigned index) const {
|
||||||
|
assert(index < getNumIndices() && "Index out of bounds for GlobalValue!");
|
||||||
|
Type *GlobalValueType = getType()->as<PointerType>()->getBaseType();
|
||||||
|
for (unsigned i = 0; i < index; i++) {
|
||||||
|
GlobalValueType = GlobalValueType->as<ArrayType>()->getElementType();
|
||||||
|
}
|
||||||
|
return GlobalValueType->as<ArrayType>()->getNumElements();
|
||||||
|
} ///< 获取维度大小(从第0个开始)
|
||||||
Value* getByIndex(unsigned index) const {
|
Value* getByIndex(unsigned index) const {
|
||||||
return initValues.getValue(index);
|
return initValues.getValue(index);
|
||||||
} ///< 通过一维偏移量index获取初始值
|
} ///< 通过一维偏移量index获取初始值
|
||||||
Value* getByIndices(const std::vector<Value *> &indices) const {
|
Value* getByIndices(const std::vector<Value *> &indices) const {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
Type *GlobalValueType = getType()->as<PointerType>()->getBaseType();
|
||||||
for (size_t i = 0; i < indices.size(); i++) {
|
for (size_t i = 0; i < indices.size(); i++) {
|
||||||
// Ensure dims[i] and indices[i] are ConstantInteger and retrieve their values correctly
|
// Ensure dims[i] and indices[i] are ConstantInteger and retrieve their values correctly
|
||||||
auto dim_val = dynamic_cast<ConstantInteger*>(getDim(i));
|
// GlobalValueType->as<ArrayType>()->getNumElements();
|
||||||
|
auto dim_val = GlobalValueType->as<ArrayType>()->getNumElements();
|
||||||
auto idx_val = dynamic_cast<ConstantInteger*>(indices[i]);
|
auto idx_val = dynamic_cast<ConstantInteger*>(indices[i]);
|
||||||
assert(dim_val && idx_val && "Dims and indices must be constant integers");
|
assert(dim_val && idx_val && "Dims and indices must be constant integers");
|
||||||
index = dim_val->getInt() * index + idx_val->getInt();
|
index = dim_val * index + idx_val->getInt();
|
||||||
|
GlobalValueType = GlobalValueType->as<ArrayType>()->getElementType();
|
||||||
}
|
}
|
||||||
return getByIndex(index);
|
return getByIndex(index);
|
||||||
} ///< 通过多维索引indices获取初始值
|
} ///< 通过多维索引indices获取初始值
|
||||||
@@ -1406,7 +1421,7 @@ public:
|
|||||||
}; // class GlobalValue
|
}; // class GlobalValue
|
||||||
|
|
||||||
|
|
||||||
class ConstantVariable : public User {
|
class ConstantVariable : public Value {
|
||||||
friend class Module;
|
friend class Module;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -1417,31 +1432,45 @@ class ConstantVariable : public User {
|
|||||||
protected:
|
protected:
|
||||||
ConstantVariable(Module *parent, Type *type, const std::string &name, const ValueCounter &init,
|
ConstantVariable(Module *parent, Type *type, const std::string &name, const ValueCounter &init,
|
||||||
const std::vector<Value *> &dims = {})
|
const std::vector<Value *> &dims = {})
|
||||||
: User(type, name), parent(parent) {
|
: Value(type, name), parent(parent) {
|
||||||
assert(type->isPointer());
|
assert(type->isPointer());
|
||||||
numDims = dims.size();
|
numDims = dims.size();
|
||||||
initValues = init;
|
initValues = init;
|
||||||
addOperands(dims);
|
// addOperands(dims); 同GlobalValue,维度信息已经被记录到Type中,dim只是为了方便初始化
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
unsigned getNumIndices() const {
|
||||||
|
return numDims;
|
||||||
|
} ///< 获取索引数量
|
||||||
|
unsigned getIndex(unsigned index) const {
|
||||||
|
assert(index < getNumIndices() && "Index out of bounds for ConstantVariable!");
|
||||||
|
Type *ConstantVariableType = getType()->as<PointerType>()->getBaseType();
|
||||||
|
for (unsigned i = 0; i < index; i++) {
|
||||||
|
ConstantVariableType = ConstantVariableType->as<ArrayType>()->getElementType();
|
||||||
|
}
|
||||||
|
return ConstantVariableType->as<ArrayType>()->getNumElements();
|
||||||
|
} ///< 获取索引个数(从第0个开始)
|
||||||
Value* getByIndex(unsigned index) const { return initValues.getValue(index); } ///< 通过一维位置index获取值
|
Value* getByIndex(unsigned index) const { return initValues.getValue(index); } ///< 通过一维位置index获取值
|
||||||
Value* getByIndices(const std::vector<Value *> &indices) const {
|
Value* getByIndices(const std::vector<Value *> &indices) const {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
// 计算偏移量
|
// 计算偏移量
|
||||||
|
Type *ConstantVariableType = getType()->as<PointerType>()->getBaseType();
|
||||||
for (size_t i = 0; i < indices.size(); i++) {
|
for (size_t i = 0; i < indices.size(); i++) {
|
||||||
// Ensure dims[i] and indices[i] are ConstantInteger and retrieve their values correctly
|
// Ensure dims[i] and indices[i] are ConstantInteger and retrieve their values correctly
|
||||||
auto dim_val = dynamic_cast<ConstantInteger*>(getDim(i));
|
// ConstantVariableType->as<ArrayType>()->getNumElements();
|
||||||
|
auto dim_val = ConstantVariableType->as<ArrayType>()->getNumElements();
|
||||||
auto idx_val = dynamic_cast<ConstantInteger*>(indices[i]);
|
auto idx_val = dynamic_cast<ConstantInteger*>(indices[i]);
|
||||||
assert(dim_val && idx_val && "Dims and indices must be constant integers");
|
assert(dim_val && idx_val && "Dims and indices must be constant integers");
|
||||||
index = dim_val->getInt() * index + idx_val->getInt();
|
index = dim_val * index + idx_val->getInt();
|
||||||
|
ConstantVariableType = ConstantVariableType->as<ArrayType>()->getElementType();
|
||||||
}
|
}
|
||||||
|
|
||||||
return getByIndex(index);
|
return getByIndex(index);
|
||||||
} ///< 通过多维索引indices获取初始值
|
} ///< 通过多维索引indices获取初始值
|
||||||
unsigned getNumDims() const { return numDims; } ///< 获取维度数量
|
// unsigned getNumDims() const { return numDims; } ///< 获取维度数量
|
||||||
Value* getDim(unsigned index) const { return getOperand(index); } ///< 获取位置为index的维度
|
// Value* getDim(unsigned index) const { return getOperand(index); } ///< 获取位置为index的维度
|
||||||
auto getDims() const { return getOperands(); } ///< 获取维度列表
|
// auto getDims() const { return getOperands(); } ///< 获取维度列表
|
||||||
const ValueCounter& getInitValues() const { return initValues; } ///< 获取初始值
|
const ValueCounter& getInitValues() const { return initValues; } ///< 获取初始值
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1457,7 +1486,7 @@ class SymbolTable {
|
|||||||
SymbolTableNode *curNode{}; ///< 当前所在的作用域(符号表节点)
|
SymbolTableNode *curNode{}; ///< 当前所在的作用域(符号表节点)
|
||||||
std::map<std::string, unsigned> variableIndex; ///< 变量命名索引表
|
std::map<std::string, unsigned> variableIndex; ///< 变量命名索引表
|
||||||
std::vector<std::unique_ptr<GlobalValue>> globals; ///< 全局变量列表
|
std::vector<std::unique_ptr<GlobalValue>> globals; ///< 全局变量列表
|
||||||
std::vector<std::unique_ptr<ConstantVariable>> consts; ///< 常量列表
|
std::vector<std::unique_ptr<ConstantVariable>> globalconsts; ///< 全局常量列表
|
||||||
std::vector<std::unique_ptr<SymbolTableNode>> nodeList; ///< 符号表节点列表
|
std::vector<std::unique_ptr<SymbolTableNode>> nodeList; ///< 符号表节点列表
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -1466,7 +1495,7 @@ class SymbolTable {
|
|||||||
Value* getVariable(const std::string &name) const; ///< 根据名字name以及当前作用域获取变量
|
Value* getVariable(const std::string &name) const; ///< 根据名字name以及当前作用域获取变量
|
||||||
Value* addVariable(const std::string &name, Value *variable); ///< 添加变量
|
Value* addVariable(const std::string &name, Value *variable); ///< 添加变量
|
||||||
std::vector<std::unique_ptr<GlobalValue>>& getGlobals(); ///< 获取全局变量列表
|
std::vector<std::unique_ptr<GlobalValue>>& getGlobals(); ///< 获取全局变量列表
|
||||||
const std::vector<std::unique_ptr<ConstantVariable>>& getConsts() const; ///< 获取常量列表
|
const std::vector<std::unique_ptr<ConstantVariable>>& getConsts() const; ///< 获取全局常量列表
|
||||||
void enterNewScope(); ///< 进入新的作用域
|
void enterNewScope(); ///< 进入新的作用域
|
||||||
void leaveScope(); ///< 离开作用域
|
void leaveScope(); ///< 离开作用域
|
||||||
bool isInGlobalScope() const; ///< 是否位于全局作用域
|
bool isInGlobalScope() const; ///< 是否位于全局作用域
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ class IRBuilder {
|
|||||||
UnaryInst * createFNotInst(Value *operand, const std::string &name = "") {
|
UnaryInst * createFNotInst(Value *operand, const std::string &name = "") {
|
||||||
return createUnaryInst(Instruction::kFNot, Type::getIntType(), operand, name);
|
return createUnaryInst(Instruction::kFNot, Type::getIntType(), operand, name);
|
||||||
} ///< 创建浮点取非指令
|
} ///< 创建浮点取非指令
|
||||||
UnaryInst * createIToFInst(Value *operand, const std::string &name = "") {
|
UnaryInst * createItoFInst(Value *operand, const std::string &name = "") {
|
||||||
return createUnaryInst(Instruction::kItoF, Type::getFloatType(), operand, name);
|
return createUnaryInst(Instruction::kItoF, Type::getFloatType(), operand, name);
|
||||||
} ///< 创建整型转浮点指令
|
} ///< 创建整型转浮点指令
|
||||||
UnaryInst * createBitItoFInst(Value *operand, const std::string &name = "") {
|
UnaryInst * createBitItoFInst(Value *operand, const std::string &name = "") {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ public:
|
|||||||
public:
|
public:
|
||||||
void printIR();
|
void printIR();
|
||||||
void printGlobalVariable();
|
void printGlobalVariable();
|
||||||
|
void printGlobalConstant();
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
#include "SysYIRPrinter.h"
|
#include "SysYIRPrinter.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <limits>
|
||||||
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "IR.h" // 确保IR.h包含了ArrayType、GetElementPtrInst等的定义
|
#include "IR.h" // 确保IR.h包含了ArrayType、GetElementPtrInst等的定义
|
||||||
|
|
||||||
@@ -13,6 +16,7 @@ void SysYPrinter::printIR() {
|
|||||||
//TODO: Print target datalayout and triple (minimal required by LLVM)
|
//TODO: Print target datalayout and triple (minimal required by LLVM)
|
||||||
|
|
||||||
printGlobalVariable();
|
printGlobalVariable();
|
||||||
|
printGlobalConstant();
|
||||||
|
|
||||||
for (const auto &iter : functions) {
|
for (const auto &iter : functions) {
|
||||||
if (iter.second->getName() == "main") {
|
if (iter.second->getName() == "main") {
|
||||||
@@ -60,16 +64,21 @@ std::string SysYPrinter::getValueName(Value *value) {
|
|||||||
} else if (auto constInt = dynamic_cast<ConstantInteger*>(value)) { // 优先匹配具体的常量类型
|
} else if (auto constInt = dynamic_cast<ConstantInteger*>(value)) { // 优先匹配具体的常量类型
|
||||||
return std::to_string(constInt->getInt());
|
return std::to_string(constInt->getInt());
|
||||||
} else if (auto constFloat = dynamic_cast<ConstantFloating*>(value)) { // 优先匹配具体的常量类型
|
} else if (auto constFloat = dynamic_cast<ConstantFloating*>(value)) { // 优先匹配具体的常量类型
|
||||||
return std::to_string(constFloat->getFloat());
|
std::ostringstream oss;
|
||||||
|
oss << std::scientific << std::setprecision(std::numeric_limits<float>::max_digits10) << constFloat->getFloat();
|
||||||
|
return oss.str();
|
||||||
} else if (auto constUndef = dynamic_cast<UndefinedValue*>(value)) { // 如果有Undef类型
|
} else if (auto constUndef = dynamic_cast<UndefinedValue*>(value)) { // 如果有Undef类型
|
||||||
return "undef";
|
return "undef";
|
||||||
} else if (auto constVal = dynamic_cast<ConstantValue*>(value)) { // fallback for generic ConstantValue
|
} else if (auto constVal = dynamic_cast<ConstantValue*>(value)) { // fallback for generic ConstantValue
|
||||||
// 这里的逻辑可能需要根据你ConstantValue的实际设计调整
|
// 这里的逻辑可能需要根据你ConstantValue的实际设计调整
|
||||||
// 确保它能处理所有可能的ConstantValue
|
// 确保它能处理所有可能的ConstantValue
|
||||||
if (constVal->getType()->isFloat()) {
|
if (auto constInt = dynamic_cast<ConstantInteger*>(value)) { // 优先匹配具体的常量类型
|
||||||
return std::to_string(constVal->getFloat());
|
return std::to_string(constInt->getInt());
|
||||||
|
} else if (auto constFloat = dynamic_cast<ConstantFloating*>(value)) { // 优先匹配具体的常量类型
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << std::scientific << std::setprecision(std::numeric_limits<float>::max_digits10) << constFloat->getFloat();
|
||||||
|
return oss.str();
|
||||||
}
|
}
|
||||||
return std::to_string(constVal->getInt());
|
|
||||||
} else if (auto constVar = dynamic_cast<ConstantVariable*>(value)) {
|
} else if (auto constVar = dynamic_cast<ConstantVariable*>(value)) {
|
||||||
return constVar->getName(); // 假设ConstantVariable有自己的名字或通过getByIndices获取值
|
return constVar->getName(); // 假设ConstantVariable有自己的名字或通过getByIndices获取值
|
||||||
} else if (auto argVar = dynamic_cast<Argument*>(value)) {
|
} else if (auto argVar = dynamic_cast<Argument*>(value)) {
|
||||||
@@ -137,6 +146,48 @@ void SysYPrinter::printGlobalVariable() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SysYPrinter::printGlobalConstant() {
|
||||||
|
auto &globalConstants = pModule->getConsts();
|
||||||
|
|
||||||
|
for (const auto &globalConstant : globalConstants) {
|
||||||
|
std::cout << "@" << globalConstant->getName() << " = global constant ";
|
||||||
|
|
||||||
|
// 全局变量的类型是一个指针,指向其基类型 (可能是 ArrayType 或 Integer/FloatType)
|
||||||
|
auto globalVarBaseType = dynamic_cast<PointerType *>(globalConstant->getType())->getBaseType();
|
||||||
|
printType(globalVarBaseType); // 打印全局变量的实际类型 (例如 i32 或 [10 x i32])
|
||||||
|
|
||||||
|
std::cout << " ";
|
||||||
|
|
||||||
|
// 检查是否是数组类型 (通过检查 globalVarBaseType 是否是 ArrayType)
|
||||||
|
if (globalVarBaseType->isArray()) {
|
||||||
|
// 数组初始化器
|
||||||
|
std::cout << "["; // LLVM IR 数组初始化器格式: [type value, type value, ...]
|
||||||
|
auto values = globalConstant->getInitValues(); // 假设 getInitValues() 返回一个 ValueCounter
|
||||||
|
const std::vector<sysy::Value *> &counterValues = values.getValues(); // 获取所有值
|
||||||
|
|
||||||
|
for (size_t i = 0; i < counterValues.size(); i++) {
|
||||||
|
if (i > 0) std::cout << ", ";
|
||||||
|
// 打印元素类型,这个元素类型应该是数组的最终元素类型,例如 i32 或 float
|
||||||
|
// 可以从 globalVarBaseType 逐层剥离得到最终元素类型,但这里简化为直接从值获取
|
||||||
|
printType(counterValues[i]->getType());
|
||||||
|
std::cout << " ";
|
||||||
|
printValue(counterValues[i]);
|
||||||
|
}
|
||||||
|
std::cout << "]";
|
||||||
|
} else {
|
||||||
|
// 标量初始化器
|
||||||
|
// 假设标量全局变量的初始化值通过 getByIndex(0) 获取
|
||||||
|
Value* initVal = globalConstant->getByIndex(0);
|
||||||
|
printType(initVal->getType()); // 打印标量值的类型
|
||||||
|
std::cout << " ";
|
||||||
|
printValue(initVal); // 打印标量值
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << ", align 4" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SysYPrinter::printBlock(BasicBlock *block) {
|
void SysYPrinter::printBlock(BasicBlock *block) {
|
||||||
std::cout << getBlockName(block);
|
std::cout << getBlockName(block);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user