[midend-llvnirprint]修改浮点为字面值打印,修复assign的类型推断
This commit is contained in:
@@ -13,16 +13,15 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
inline std::string getMachineCode(float fval) {
|
inline std::string getMachineCode(float fval) {
|
||||||
// LLVM IR要求float也使用64位十六进制表示
|
|
||||||
// 将float扩展为double精度格式
|
|
||||||
double dval = static_cast<double>(fval);
|
|
||||||
uint64_t bits = *reinterpret_cast<uint64_t*>(&dval);
|
|
||||||
|
|
||||||
// 如果是0,直接返回
|
// 如果是0,直接返回
|
||||||
if (bits == 0 || fval == 0.0f) {
|
if (fval == 0.0f) {
|
||||||
return "0x0000000000000000";
|
return "0x0000000000000000";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 正确的float到double扩展:先转换值,再获取double的位表示
|
||||||
|
double dval = static_cast<double>(fval);
|
||||||
|
uint64_t bits = *reinterpret_cast<uint64_t*>(&dval);
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "0x" << std::hex << std::uppercase << std::setfill('0') << std::setw(16) << bits;
|
ss << "0x" << std::hex << std::uppercase << std::setfill('0') << std::setw(16) << bits;
|
||||||
return ss.str();
|
return ss.str();
|
||||||
@@ -90,11 +89,18 @@ 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) {
|
||||||
// 对于常量,只打印值,不打印类型(类型已经在指令中单独打印了)
|
|
||||||
if (auto constInt = dynamic_cast<const ConstantInteger*>(constValue)) {
|
if (auto constInt = dynamic_cast<const ConstantInteger*>(constValue)) {
|
||||||
os << constInt->getInt();
|
os << constInt->getInt();
|
||||||
} else if (auto constFloat = dynamic_cast<const ConstantFloating*>(constValue)) {
|
} else if (auto constFloat = dynamic_cast<const ConstantFloating*>(constValue)) {
|
||||||
os << getMachineCode(constFloat->getFloat());
|
float f = constFloat->getFloat();
|
||||||
|
char buffer[64];
|
||||||
|
snprintf(buffer, sizeof(buffer), "%.17g", f);
|
||||||
|
std::string str(buffer);
|
||||||
|
if (str.find('.') == std::string::npos && str.find('e') == std::string::npos) {
|
||||||
|
str += ".0";
|
||||||
|
}
|
||||||
|
os << str;
|
||||||
|
|
||||||
} else if (auto undefVal = dynamic_cast<const UndefinedValue*>(constValue)) {
|
} else if (auto undefVal = dynamic_cast<const UndefinedValue*>(constValue)) {
|
||||||
os << "undef";
|
os << "undef";
|
||||||
}
|
}
|
||||||
@@ -586,10 +592,18 @@ void ConstantValue::print(std::ostream &os) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ConstantInteger::print(std::ostream &os) const {
|
void ConstantInteger::print(std::ostream &os) const {
|
||||||
os << "i32 " << this->getInt();
|
os << this->getInt();
|
||||||
}
|
}
|
||||||
void ConstantFloating::print(std::ostream &os) const {
|
void ConstantFloating::print(std::ostream &os) const {
|
||||||
os << "float " << getMachineCode(this->getFloat());
|
float f = this->getFloat();
|
||||||
|
|
||||||
|
char buffer[64];
|
||||||
|
snprintf(buffer, sizeof(buffer), "%.17g", f);
|
||||||
|
std::string str(buffer);
|
||||||
|
if (str.find('.') == std::string::npos && str.find('e') == std::string::npos) {
|
||||||
|
str += ".0";
|
||||||
|
}
|
||||||
|
os << str;
|
||||||
}
|
}
|
||||||
void UndefinedValue::print(std::ostream &os) const {
|
void UndefinedValue::print(std::ostream &os) const {
|
||||||
os << this->getType() << " undef";
|
os << this->getType() << " undef";
|
||||||
|
|||||||
@@ -1297,6 +1297,45 @@ std::any SysYIRGenerator::visitAssignStmt(SysYParser::AssignStmtContext *ctx) {
|
|||||||
if (dynamic_cast<AllocaInst*>(variable) || dynamic_cast<GlobalValue*>(variable)) {
|
if (dynamic_cast<AllocaInst*>(variable) || dynamic_cast<GlobalValue*>(variable)) {
|
||||||
LValue = variable;
|
LValue = variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 标量变量的类型推断
|
||||||
|
Type* LType = builder.getIndexedType(variable->getType(), indices);
|
||||||
|
|
||||||
|
Value* RValue = computeExp(ctx->exp(), LType); // 右值计算
|
||||||
|
Type* RType = RValue->getType();
|
||||||
|
|
||||||
|
// TODO:computeExp处理了类型转换,可以考虑删除判断逻辑
|
||||||
|
if (LType != RType) {
|
||||||
|
ConstantValue *constValue = dynamic_cast<ConstantValue *>(RValue);
|
||||||
|
if (constValue != nullptr) {
|
||||||
|
if (LType == Type::getFloatType()) {
|
||||||
|
if(dynamic_cast<ConstantInteger *>(constValue)) {
|
||||||
|
// 如果是整型常量,转换为浮点型
|
||||||
|
RValue = ConstantFloating::get(static_cast<float>(constValue->getInt()));
|
||||||
|
} else if (dynamic_cast<ConstantFloating *>(constValue)) {
|
||||||
|
// 如果是浮点型常量,直接使用
|
||||||
|
RValue = ConstantFloating::get(static_cast<float>(constValue->getFloat()));
|
||||||
|
}
|
||||||
|
} else { // 假设如果不是浮点型,就是整型
|
||||||
|
if(dynamic_cast<ConstantFloating *>(constValue)) {
|
||||||
|
// 如果是浮点型常量,转换为整型
|
||||||
|
RValue = ConstantInteger::get(static_cast<int>(constValue->getFloat()));
|
||||||
|
} else if (dynamic_cast<ConstantInteger *>(constValue)) {
|
||||||
|
// 如果是整型常量,直接使用
|
||||||
|
RValue = ConstantInteger::get(static_cast<int>(constValue->getInt()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (LType == Type::getFloatType() && RType != Type::getFloatType()) {
|
||||||
|
RValue = builder.createItoFInst(RValue);
|
||||||
|
} else if (LType != Type::getFloatType() && RType == Type::getFloatType()) {
|
||||||
|
RValue = builder.createFtoIInst(RValue);
|
||||||
|
}
|
||||||
|
// 如果两者都是同一类型,就不需要转换
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.createStoreInst(RValue, LValue);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// 对于数组或多维数组的左值处理
|
// 对于数组或多维数组的左值处理
|
||||||
@@ -1334,52 +1373,47 @@ std::any SysYIRGenerator::visitAssignStmt(SysYParser::AssignStmtContext *ctx) {
|
|||||||
}
|
}
|
||||||
// 左值为地址
|
// 左值为地址
|
||||||
LValue = getGEPAddressInst(gepBasePointer, gepIndices);
|
LValue = getGEPAddressInst(gepBasePointer, gepIndices);
|
||||||
}
|
|
||||||
|
// 数组变量的类型推断,使用gepIndices和gepBasePointer的类型
|
||||||
|
Type* LType = builder.getIndexedType(gepBasePointer->getType(), gepIndices);
|
||||||
|
|
||||||
|
Value* RValue = computeExp(ctx->exp(), LType); // 右值计算
|
||||||
|
Type* RType = RValue->getType();
|
||||||
|
|
||||||
// Value* RValue = std::any_cast<Value *>(visitExp(ctx->exp())); // 右值
|
// TODO:computeExp处理了类型转换,可以考虑删除判断逻辑
|
||||||
|
if (LType != RType) {
|
||||||
// 先推断 LValue 的类型
|
ConstantValue *constValue = dynamic_cast<ConstantValue *>(RValue);
|
||||||
// 如果 LValue 是指向数组的指针,则需要根据 indices 获取正确的类型
|
if (constValue != nullptr) {
|
||||||
// 如果 LValue 是标量,则直接使用其类型
|
if (LType == Type::getFloatType()) {
|
||||||
// 注意:LValue 的类型可能是指向数组的指针 (e.g., int(*)[3]) 或者指向标量的指针 (e.g., int*) 也能推断
|
if(dynamic_cast<ConstantInteger *>(constValue)) {
|
||||||
Type* LType = builder.getIndexedType(variable->getType(), indices);
|
// 如果是整型常量,转换为浮点型
|
||||||
|
RValue = ConstantFloating::get(static_cast<float>(constValue->getInt()));
|
||||||
Value* RValue = computeExp(ctx->exp(), LType); // 右值计算
|
} else if (dynamic_cast<ConstantFloating *>(constValue)) {
|
||||||
Type* RType = RValue->getType();
|
// 如果是浮点型常量,直接使用
|
||||||
|
RValue = ConstantFloating::get(static_cast<float>(constValue->getFloat()));
|
||||||
// TODO:computeExp处理了类型转换,可以考虑删除判断逻辑
|
}
|
||||||
if (LType != RType) {
|
} else { // 假设如果不是浮点型,就是整型
|
||||||
ConstantValue *constValue = dynamic_cast<ConstantValue *>(RValue);
|
if(dynamic_cast<ConstantFloating *>(constValue)) {
|
||||||
if (constValue != nullptr) {
|
// 如果是浮点型常量,转换为整型
|
||||||
if (LType == Type::getFloatType()) {
|
RValue = ConstantInteger::get(static_cast<int>(constValue->getFloat()));
|
||||||
if(dynamic_cast<ConstantInteger *>(constValue)) {
|
} else if (dynamic_cast<ConstantInteger *>(constValue)) {
|
||||||
// 如果是整型常量,转换为浮点型
|
// 如果是整型常量,直接使用
|
||||||
RValue = ConstantFloating::get(static_cast<float>(constValue->getInt()));
|
RValue = ConstantInteger::get(static_cast<int>(constValue->getInt()));
|
||||||
} else if (dynamic_cast<ConstantFloating *>(constValue)) {
|
}
|
||||||
// 如果是浮点型常量,直接使用
|
|
||||||
RValue = ConstantFloating::get(static_cast<float>(constValue->getFloat()));
|
|
||||||
}
|
}
|
||||||
} else { // 假设如果不是浮点型,就是整型
|
} else {
|
||||||
if(dynamic_cast<ConstantFloating *>(constValue)) {
|
if (LType == Type::getFloatType() && RType != Type::getFloatType()) {
|
||||||
// 如果是浮点型常量,转换为整型
|
RValue = builder.createItoFInst(RValue);
|
||||||
RValue = ConstantInteger::get(static_cast<int>(constValue->getFloat()));
|
} else if (LType != Type::getFloatType() && RType == Type::getFloatType()) {
|
||||||
} else if (dynamic_cast<ConstantInteger *>(constValue)) {
|
RValue = builder.createFtoIInst(RValue);
|
||||||
// 如果是整型常量,直接使用
|
|
||||||
RValue = ConstantInteger::get(static_cast<int>(constValue->getInt()));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// 如果两者都是同一类型,就不需要转换
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (LType == Type::getFloatType() && RType != Type::getFloatType()) {
|
|
||||||
RValue = builder.createItoFInst(RValue);
|
|
||||||
} else if (LType != Type::getFloatType() && RType == Type::getFloatType()) {
|
|
||||||
RValue = builder.createFtoIInst(RValue);
|
|
||||||
}
|
|
||||||
// 如果两者都是同一类型,就不需要转换
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
builder.createStoreInst(RValue, LValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.createStoreInst(RValue, LValue);
|
|
||||||
invalidateExpressionsOnStore(LValue);
|
invalidateExpressionsOnStore(LValue);
|
||||||
return std::any();
|
return std::any();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user