[midend-llvmirprint]修复部分打印逻辑,修复生成IR时的基本块错误的前后驱关系链接
This commit is contained in:
@ -13,10 +13,19 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
inline std::string getMachineCode(float fval) {
|
inline std::string getMachineCode(float fval) {
|
||||||
uint32_t mrf = *reinterpret_cast<uint32_t*>(&fval);
|
// LLVM IR要求float也使用64位十六进制表示
|
||||||
|
// 将float扩展为double精度格式
|
||||||
|
double dval = static_cast<double>(fval);
|
||||||
|
uint64_t bits = *reinterpret_cast<uint64_t*>(&dval);
|
||||||
|
|
||||||
|
// 如果是0,直接返回
|
||||||
|
if (bits == 0 || fval == 0.0f) {
|
||||||
|
return "0x0000000000000000";
|
||||||
|
}
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << std::hex << std::uppercase << std::setfill('0') << std::setw(8) << mrf;
|
ss << "0x" << std::hex << std::uppercase << std::setfill('0') << std::setw(16) << bits;
|
||||||
return "0x" + ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -638,7 +647,7 @@ void PhiInst::print(std::ostream &os) const {
|
|||||||
}
|
}
|
||||||
os << " [";
|
os << " [";
|
||||||
printOperand(os, getIncomingValue(i));
|
printOperand(os, getIncomingValue(i));
|
||||||
os << ", ";
|
os << ", %";
|
||||||
printBlockName(os, getIncomingBlock(i));
|
printBlockName(os, getIncomingBlock(i));
|
||||||
os << "]";
|
os << "]";
|
||||||
}
|
}
|
||||||
@ -723,27 +732,34 @@ void AllocaInst::print(std::ostream &os) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BinaryInst::print(std::ostream &os) const {
|
void BinaryInst::print(std::ostream &os) const {
|
||||||
printVarName(os, this) << " = ";
|
|
||||||
|
|
||||||
auto kind = getKind();
|
auto kind = getKind();
|
||||||
|
|
||||||
// 检查是否为比较指令
|
// 检查是否为比较指令
|
||||||
if (kind == kICmpEQ || kind == kICmpNE || kind == kICmpLT ||
|
if (kind == kICmpEQ || kind == kICmpNE || kind == kICmpLT ||
|
||||||
kind == kICmpGT || kind == kICmpLE || kind == kICmpGE) {
|
kind == kICmpGT || kind == kICmpLE || kind == kICmpGE) {
|
||||||
// 整数比较指令
|
// 整数比较指令 - 生成临时i1结果然后转换为i32
|
||||||
os << getKindString() << " " << *getLhs()->getType() << " ";
|
static int tmpCmpCounter = 0;
|
||||||
|
std::string tmpName = "tmp_icmp_" + std::to_string(++tmpCmpCounter);
|
||||||
|
os << "%" << tmpName << " = " << getKindString() << " " << *getLhs()->getType() << " ";
|
||||||
printOperand(os, getLhs());
|
printOperand(os, getLhs());
|
||||||
os << ", ";
|
os << ", ";
|
||||||
printOperand(os, getRhs());
|
printOperand(os, getRhs());
|
||||||
|
os << "\n ";
|
||||||
|
printVarName(os, this) << " = zext i1 %" << tmpName << " to i32";
|
||||||
} else if (kind == kFCmpEQ || kind == kFCmpNE || kind == kFCmpLT ||
|
} else if (kind == kFCmpEQ || kind == kFCmpNE || kind == kFCmpLT ||
|
||||||
kind == kFCmpGT || kind == kFCmpLE || kind == kFCmpGE) {
|
kind == kFCmpGT || kind == kFCmpLE || kind == kFCmpGE) {
|
||||||
// 浮点比较指令
|
// 浮点比较指令 - 生成临时i1结果然后转换为i32
|
||||||
os << getKindString() << " " << *getLhs()->getType() << " ";
|
static int tmpCmpCounter = 0;
|
||||||
|
std::string tmpName = "tmp_fcmp_" + std::to_string(++tmpCmpCounter);
|
||||||
|
os << "%" << tmpName << " = " << getKindString() << " " << *getLhs()->getType() << " ";
|
||||||
printOperand(os, getLhs());
|
printOperand(os, getLhs());
|
||||||
os << ", ";
|
os << ", ";
|
||||||
printOperand(os, getRhs());
|
printOperand(os, getRhs());
|
||||||
|
os << "\n ";
|
||||||
|
printVarName(os, this) << " = zext i1 %" << tmpName << " to i32";
|
||||||
} else {
|
} else {
|
||||||
// 算术和逻辑指令
|
// 算术和逻辑指令
|
||||||
|
printVarName(os, this) << " = ";
|
||||||
os << getKindString() << " " << *getType() << " ";
|
os << getKindString() << " " << *getType() << " ";
|
||||||
printOperand(os, getLhs());
|
printOperand(os, getLhs());
|
||||||
os << ", ";
|
os << ", ";
|
||||||
@ -769,38 +785,15 @@ void UncondBrInst::print(std::ostream &os) const {
|
|||||||
void CondBrInst::print(std::ostream &os) const {
|
void CondBrInst::print(std::ostream &os) const {
|
||||||
Value* condition = getCondition();
|
Value* condition = getCondition();
|
||||||
|
|
||||||
// 检查条件是否来自比较指令
|
// 由于所有条件都是i32类型(包括比较结果),统一转换为i1
|
||||||
if (auto* binaryInst = dynamic_cast<BinaryInst*>(condition)) {
|
static int tmpCondCounter = 0;
|
||||||
auto kind = binaryInst->getKind();
|
std::string condName = condition->getName();
|
||||||
if (kind == kICmpEQ || kind == kICmpNE || kind == kICmpLT ||
|
if (condName.empty()) {
|
||||||
kind == kICmpGT || kind == kICmpLE || kind == kICmpGE ||
|
condName = "const" + std::to_string(++tmpCondCounter);
|
||||||
kind == kFCmpEQ || kind == kFCmpNE || kind == kFCmpLT ||
|
|
||||||
kind == kFCmpGT || kind == kFCmpLE || kind == kFCmpGE) {
|
|
||||||
// 比较指令返回i1类型,直接使用
|
|
||||||
os << "br i1 ";
|
|
||||||
printOperand(os, condition);
|
|
||||||
} else {
|
|
||||||
// 其他指令返回i32,需要转换
|
|
||||||
static int tmpCondCounter = 0;
|
|
||||||
std::string condName = condition->getName();
|
|
||||||
if (condName.empty()) {
|
|
||||||
condName = "const" + std::to_string(++tmpCondCounter);
|
|
||||||
}
|
|
||||||
os << "%tmp_cond_" << condName << " = icmp ne i32 ";
|
|
||||||
printOperand(os, condition);
|
|
||||||
os << ", 0\n br i1 %tmp_cond_" << condName;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 对于非BinaryInst的条件(如变量),假设是i32需要转换
|
|
||||||
static int tmpCondCounter = 0;
|
|
||||||
std::string condName = condition->getName();
|
|
||||||
if (condName.empty()) {
|
|
||||||
condName = "const" + std::to_string(++tmpCondCounter);
|
|
||||||
}
|
|
||||||
os << "%tmp_cond_" << condName << " = icmp ne i32 ";
|
|
||||||
printOperand(os, condition);
|
|
||||||
os << ", 0\n br i1 %tmp_cond_" << condName;
|
|
||||||
}
|
}
|
||||||
|
os << "%tmp_cond_" << condName << " = icmp ne i32 ";
|
||||||
|
printOperand(os, condition);
|
||||||
|
os << ", 0\n br i1 %tmp_cond_" << condName;
|
||||||
|
|
||||||
os << ", label %";
|
os << ", label %";
|
||||||
printBlockName(os, getThenBlock());
|
printBlockName(os, getThenBlock());
|
||||||
@ -1079,14 +1072,26 @@ auto SymbolTable::addVariable(const std::string &name, Value *variable) -> Value
|
|||||||
displayName = name.substr(0, 100) + "_hash_" + std::to_string(hash);
|
displayName = name.substr(0, 100) + "_hash_" + std::to_string(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 区分全局变量和局部变量的命名
|
||||||
|
bool isGlobalVariable = (dynamic_cast<GlobalValue *>(variable) != nullptr) ||
|
||||||
|
(dynamic_cast<ConstantVariable *>(variable) != nullptr);
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
if (iter != variableIndex.end()) {
|
if (iter != variableIndex.end()) {
|
||||||
ss << displayName << iter->second ;
|
index = iter->second;
|
||||||
iter->second += 1;
|
iter->second += 1;
|
||||||
} else {
|
} else {
|
||||||
variableIndex.emplace(name, 1);
|
variableIndex.emplace(name, 1);
|
||||||
ss << displayName << 0 ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isGlobalVariable) {
|
||||||
|
// 全局变量不使用 local_ 前缀
|
||||||
|
ss << displayName << index;
|
||||||
|
} else {
|
||||||
|
// 局部变量使用 "local_" 前缀确保不会和函数参数名冲突
|
||||||
|
ss << "local_" << displayName << index;
|
||||||
|
}
|
||||||
|
|
||||||
variable->setName(ss.str());
|
variable->setName(ss.str());
|
||||||
curNode->varList.emplace(name, variable);
|
curNode->varList.emplace(name, variable);
|
||||||
auto global = dynamic_cast<GlobalValue *>(variable);
|
auto global = dynamic_cast<GlobalValue *>(variable);
|
||||||
@ -1107,24 +1112,8 @@ auto SymbolTable::addVariable(const std::string &name, Value *variable) -> Value
|
|||||||
* 注册函数参数名字到符号表,确保后续的alloca变量不会使用相同的名字
|
* 注册函数参数名字到符号表,确保后续的alloca变量不会使用相同的名字
|
||||||
*/
|
*/
|
||||||
void SymbolTable::registerParameterName(const std::string &name) {
|
void SymbolTable::registerParameterName(const std::string &name) {
|
||||||
if (curNode != nullptr) {
|
// 由于局部变量现在使用 "local_" 前缀,不需要复杂的冲突避免逻辑
|
||||||
// 为当前函数作用域创建一个唯一的参数名标识
|
// 这个方法现在主要用于参数相关的记录,可以简化
|
||||||
std::string scopedName = name + "_param_" + std::to_string(reinterpret_cast<uintptr_t>(curNode));
|
|
||||||
auto iter = variableIndex.find(scopedName);
|
|
||||||
if (iter != variableIndex.end()) {
|
|
||||||
iter->second += 1;
|
|
||||||
} else {
|
|
||||||
// 注册带作用域的参数名,确保在本作用域中后续的addVariable会避免冲突
|
|
||||||
variableIndex.emplace(scopedName, 1);
|
|
||||||
}
|
|
||||||
// 同时确保原名字也有一个索引,这样addVariable会为alloca生成不同的名字
|
|
||||||
auto iter2 = variableIndex.find(name);
|
|
||||||
if (iter2 == variableIndex.end()) {
|
|
||||||
variableIndex.emplace(name, 1); // 设置为1,这样addVariable会生成name1而不是name0
|
|
||||||
} else {
|
|
||||||
iter2->second += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1546,7 +1546,7 @@ std::any SysYIRGenerator::visitWhileStmt(SysYParser::WhileStmtContext *ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
builder.createUncondBrInst(headBlock);
|
builder.createUncondBrInst(headBlock);
|
||||||
BasicBlock::conectBlocks(builder.getBasicBlock(), exitBlock);
|
BasicBlock::conectBlocks(builder.getBasicBlock(), headBlock);
|
||||||
builder.popBreakBlock();
|
builder.popBreakBlock();
|
||||||
builder.popContinueBlock();
|
builder.popContinueBlock();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user