[midend-llvmirprint]修复了gep指令对不含维度信息的数组指针的处理逻辑,修复若干打印bug,在-s ir/ird -o <llvmir.ll file>的参数下最终会打印ir到file中,优化过程中的打印逻辑待更改。
This commit is contained in:
@@ -10,6 +10,14 @@
|
|||||||
#include "IRBuilder.h"
|
#include "IRBuilder.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
inline std::string getMachineCode(float fval) {
|
||||||
|
uint32_t mrf = *reinterpret_cast<uint32_t*>(&fval);
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << std::hex << std::uppercase << std::setfill('0') << std::setw(8) << mrf;
|
||||||
|
return "0x" + ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file IR.cpp
|
* @file IR.cpp
|
||||||
*
|
*
|
||||||
@@ -44,9 +52,9 @@ ostream &interleave_call(std::ostream &os, const T &container, const std::string
|
|||||||
|
|
||||||
static inline ostream &printVarName(ostream &os, const Value *var)
|
static inline ostream &printVarName(ostream &os, const Value *var)
|
||||||
{
|
{
|
||||||
if (dynamic_cast<const GlobalValue*>(var) != nullptr) {
|
if (dynamic_cast<const GlobalValue*>(var) != nullptr ||
|
||||||
auto globalVal = dynamic_cast<const GlobalValue*>(var);
|
dynamic_cast<const ConstantVariable*>(var) != nullptr) {
|
||||||
return os << "@" << globalVal->getName();
|
return os << "@" << var->getName();
|
||||||
} else {
|
} else {
|
||||||
return os << "%" << var->getName();
|
return os << "%" << var->getName();
|
||||||
}
|
}
|
||||||
@@ -60,7 +68,14 @@ static inline ostream &printFunctionName(ostream &os, const Function *fn) {
|
|||||||
static inline ostream &printOperand(ostream &os, const Value *value) {
|
static inline ostream &printOperand(ostream &os, const Value *value) {
|
||||||
auto constValue = dynamic_cast<const ConstantValue*>(value);
|
auto constValue = dynamic_cast<const ConstantValue*>(value);
|
||||||
if (constValue != nullptr) {
|
if (constValue != nullptr) {
|
||||||
constValue->print(os);
|
// 对于常量,只打印值,不打印类型(类型已经在指令中单独打印了)
|
||||||
|
if (auto constInt = dynamic_cast<const ConstantInteger*>(constValue)) {
|
||||||
|
os << constInt->getInt();
|
||||||
|
} else if (auto constFloat = dynamic_cast<const ConstantFloating*>(constValue)) {
|
||||||
|
os << getMachineCode(constFloat->getFloat());
|
||||||
|
} else if (auto undefVal = dynamic_cast<const UndefinedValue*>(constValue)) {
|
||||||
|
os << "undef";
|
||||||
|
}
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
return printVarName(os, value);
|
return printVarName(os, value);
|
||||||
@@ -267,11 +282,11 @@ void GlobalValue::print(std::ostream& os) const {
|
|||||||
os << "zeroinitializer";
|
os << "zeroinitializer";
|
||||||
} else {
|
} else {
|
||||||
// 非零值或非基本类型,打印实际值
|
// 非零值或非基本类型,打印实际值
|
||||||
singleVal->print(os);
|
printOperand(os, singleVal);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 非常量值,打印实际值
|
// 非常量值,打印实际值
|
||||||
singleVal->print(os);
|
printOperand(os, singleVal);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 数组初始值 - 需要展开ValueCounter中的压缩表示
|
// 数组初始值 - 需要展开ValueCounter中的压缩表示
|
||||||
@@ -283,7 +298,7 @@ void GlobalValue::print(std::ostream& os) const {
|
|||||||
for (unsigned j = 0; j < numbers[i]; ++j) {
|
for (unsigned j = 0; j < numbers[i]; ++j) {
|
||||||
if (!first) os << ", ";
|
if (!first) os << ", ";
|
||||||
os << *values[i]->getType() << " ";
|
os << *values[i]->getType() << " ";
|
||||||
values[i]->print(os);
|
printOperand(os, values[i]);
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -331,11 +346,11 @@ void ConstantVariable::print(std::ostream& os) const {
|
|||||||
os << "zeroinitializer";
|
os << "zeroinitializer";
|
||||||
} else {
|
} else {
|
||||||
// 非零值或非基本类型,打印实际值
|
// 非零值或非基本类型,打印实际值
|
||||||
singleVal->print(os);
|
printOperand(os, singleVal);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 非常量值,打印实际值
|
// 非常量值,打印实际值
|
||||||
singleVal->print(os);
|
printOperand(os, singleVal);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 数组初始值 - 需要展开ValueCounter中的压缩表示
|
// 数组初始值 - 需要展开ValueCounter中的压缩表示
|
||||||
@@ -347,7 +362,7 @@ void ConstantVariable::print(std::ostream& os) const {
|
|||||||
for (unsigned j = 0; j < numbers[i]; ++j) {
|
for (unsigned j = 0; j < numbers[i]; ++j) {
|
||||||
if (!first) os << ", ";
|
if (!first) os << ", ";
|
||||||
os << *values[i]->getType() << " ";
|
os << *values[i]->getType() << " ";
|
||||||
values[i]->print(os);
|
printOperand(os, values[i]);
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -470,13 +485,6 @@ UndefinedValue* UndefinedValue::get(Type* type) {
|
|||||||
return newUndef;
|
return newUndef;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string getMachineCode(float fval) {
|
|
||||||
uint32_t mrf = *reinterpret_cast<uint32_t*>(&fval);
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << std::hex << std::uppercase << std::setfill('0') << std::setw(8) << mrf;
|
|
||||||
return "0x" + ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConstantValue::print(std::ostream &os) const {
|
void ConstantValue::print(std::ostream &os) const {
|
||||||
if(dynamic_cast<const ConstantInteger*>(this)) {
|
if(dynamic_cast<const ConstantInteger*>(this)) {
|
||||||
dynamic_cast<const ConstantInteger*>(this)->print(os);
|
dynamic_cast<const ConstantInteger*>(this)->print(os);
|
||||||
@@ -540,10 +548,17 @@ void CallInst::print(std::ostream &os) const {
|
|||||||
if(!getType()->isVoid()) {
|
if(!getType()->isVoid()) {
|
||||||
printVarName(os, this) << " = ";
|
printVarName(os, this) << " = ";
|
||||||
}
|
}
|
||||||
os << getKindString() << *getType() << " " ;
|
os << getKindString() << " " << *getType() << " " ;
|
||||||
printFunctionName(os, getCallee());
|
printFunctionName(os, getCallee());
|
||||||
os << "(";
|
os << "(";
|
||||||
interleave_call(os, getOperands());
|
|
||||||
|
// 打印参数,跳过第一个操作数(函数本身)
|
||||||
|
for (unsigned i = 1; i < getNumOperands(); ++i) {
|
||||||
|
if (i > 1) os << ", ";
|
||||||
|
auto arg = getOperand(i);
|
||||||
|
os << *arg->getType() << " ";
|
||||||
|
printOperand(os, arg);
|
||||||
|
}
|
||||||
os << ")";
|
os << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -639,7 +654,7 @@ void UncondBrInst::print(std::ostream &os) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CondBrInst::print(std::ostream &os) const {
|
void CondBrInst::print(std::ostream &os) const {
|
||||||
os << "br " << *getCondition()->getType() << " ";
|
os << "br i1 "; // 条件分支的条件总是假定为i1类型
|
||||||
printOperand(os, getCondition());
|
printOperand(os, getCondition());
|
||||||
os << ", label %";
|
os << ", label %";
|
||||||
printBlockName(os, getThenBlock());
|
printBlockName(os, getThenBlock());
|
||||||
|
|||||||
@@ -1652,11 +1652,13 @@ std::any SysYIRGenerator::visitLValue(SysYParser::LValueContext *ctx) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (allIndicesConstant) {
|
// 如果是常量变量且所有索引都是常量,并且不是数组名单独出现的情况
|
||||||
|
if (allIndicesConstant && !dims.empty()) {
|
||||||
// 如果是常量变量且所有索引都是常量,直接通过 getByIndices 获取编译时值
|
// 如果是常量变量且所有索引都是常量,直接通过 getByIndices 获取编译时值
|
||||||
// 这个方法会根据索引深度返回最终的标量值或指向子数组的指针 (作为 ConstantValue/Variable)
|
// 这个方法会根据索引深度返回最终的标量值或指向子数组的指针 (作为 ConstantValue/Variable)
|
||||||
return constVar->getByIndices(dims);
|
return constVar->getByIndices(dims);
|
||||||
}
|
}
|
||||||
|
// 如果dims为空(数组名单独出现),需要走GEP路径来实现数组到指针的退化
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 处理可变变量 (AllocaInst/GlobalValue) 或带非常量索引的常量变量
|
// 3. 处理可变变量 (AllocaInst/GlobalValue) 或带非常量索引的常量变量
|
||||||
@@ -1681,16 +1683,35 @@ std::any SysYIRGenerator::visitLValue(SysYParser::LValueContext *ctx) {
|
|||||||
} else {
|
} else {
|
||||||
gepBasePointer = alloc;
|
gepBasePointer = alloc;
|
||||||
gepIndices.push_back(ConstantInteger::get(0));
|
gepIndices.push_back(ConstantInteger::get(0));
|
||||||
gepIndices.insert(gepIndices.end(), dims.begin(), dims.end());
|
if (dims.empty() && declaredNumDims > 0) {
|
||||||
|
// 数组名单独出现(没有索引):在SysY中,数组名应该退化为指向第一个元素的指针
|
||||||
|
// 需要添加额外的0索引来获取第一个元素的地址
|
||||||
|
gepIndices.push_back(ConstantInteger::get(0));
|
||||||
|
} else {
|
||||||
|
// 正常的数组元素访问
|
||||||
|
gepIndices.insert(gepIndices.end(), dims.begin(), dims.end());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (GlobalValue *glob = dynamic_cast<GlobalValue *>(variable)) {
|
} else if (GlobalValue *glob = dynamic_cast<GlobalValue *>(variable)) {
|
||||||
gepBasePointer = glob;
|
gepBasePointer = glob;
|
||||||
gepIndices.push_back(ConstantInteger::get(0));
|
gepIndices.push_back(ConstantInteger::get(0));
|
||||||
gepIndices.insert(gepIndices.end(), dims.begin(), dims.end());
|
if (dims.empty() && declaredNumDims > 0) {
|
||||||
|
// 全局数组名单独出现(没有索引):应该退化为指向第一个元素的指针
|
||||||
|
gepIndices.push_back(ConstantInteger::get(0));
|
||||||
|
} else {
|
||||||
|
// 正常的数组元素访问
|
||||||
|
gepIndices.insert(gepIndices.end(), dims.begin(), dims.end());
|
||||||
|
}
|
||||||
} else if (ConstantVariable *constV = dynamic_cast<ConstantVariable *>(variable)) {
|
} else if (ConstantVariable *constV = dynamic_cast<ConstantVariable *>(variable)) {
|
||||||
gepBasePointer = constV;
|
gepBasePointer = constV;
|
||||||
gepIndices.push_back(ConstantInteger::get(0));
|
gepIndices.push_back(ConstantInteger::get(0));
|
||||||
gepIndices.insert(gepIndices.end(), dims.begin(), dims.end());
|
if (dims.empty() && declaredNumDims > 0) {
|
||||||
|
// 常量数组名单独出现(没有索引):应该退化为指向第一个元素的指针
|
||||||
|
gepIndices.push_back(ConstantInteger::get(0));
|
||||||
|
} else {
|
||||||
|
// 正常的数组元素访问
|
||||||
|
gepIndices.insert(gepIndices.end(), dims.begin(), dims.end());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
assert(false && "LValue variable type not supported for GEP base pointer.");
|
assert(false && "LValue variable type not supported for GEP base pointer.");
|
||||||
return static_cast<Value *>(nullptr);
|
return static_cast<Value *>(nullptr);
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
cout << "=== Init IR ===\n";
|
cout << "=== Init IR ===\n";
|
||||||
SysYPrinter(moduleIR).printIR(); // 临时打印器用于调试
|
moduleIR->print(cout); // 使用新实现的print方法直接打印IR
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建 Pass 管理器并运行优化管道
|
// 创建 Pass 管理器并运行优化管道
|
||||||
@@ -145,9 +145,21 @@ int main(int argc, char **argv) {
|
|||||||
if (argStopAfter == "ir" || argStopAfter == "ird") {
|
if (argStopAfter == "ir" || argStopAfter == "ird") {
|
||||||
// 打印最终 IR
|
// 打印最终 IR
|
||||||
cout << "=== Final IR ===\n";
|
cout << "=== Final IR ===\n";
|
||||||
SysYPrinter printer(moduleIR); // 在这里创建打印器,因为可能之前调试时用过临时打印器
|
if (!argOutputFilename.empty()) {
|
||||||
printer.printIR();
|
// 输出到指定文件
|
||||||
|
ofstream fout(argOutputFilename);
|
||||||
|
if (not fout.is_open()) {
|
||||||
|
cerr << "Failed to open output file: " << argOutputFilename << endl;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
moduleIR->print(fout);
|
||||||
|
fout.close();
|
||||||
|
} else {
|
||||||
|
// 输出到标准输出
|
||||||
|
moduleIR->print(cout);
|
||||||
|
}
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// b) 如果未停止在 IR 阶段,则继续生成汇编 (后端)
|
// b) 如果未停止在 IR 阶段,则继续生成汇编 (后端)
|
||||||
|
|||||||
Reference in New Issue
Block a user