[midend-llvmirprint]修复进度(162/199),修复若干打印问题,修复若干ir生成逻辑问题
This commit is contained in:
@@ -556,8 +556,41 @@ void BasicBlock::print(std::ostream &os) const {
|
||||
os << " ";
|
||||
printBlockName(os, this);
|
||||
os << ":\n";
|
||||
|
||||
bool reachedTerminator = false;
|
||||
for (auto &inst : instructions) {
|
||||
os << " " << *inst << '\n';
|
||||
// 跳过终结指令后的死代码
|
||||
if (reachedTerminator) {
|
||||
continue;
|
||||
}
|
||||
|
||||
os << " ";
|
||||
|
||||
// 特殊处理逻辑非指令
|
||||
if (auto* unaryInst = dynamic_cast<UnaryInst*>(inst.get())) {
|
||||
if (unaryInst->getKind() == Instruction::kNot && unaryInst->getType()->isInt()) {
|
||||
// 生成两行:先比较,再扩展
|
||||
os << "%tmp_not_" << unaryInst->getName() << " = icmp eq "
|
||||
<< *unaryInst->getOperand()->getType() << " ";
|
||||
printOperand(os, unaryInst->getOperand());
|
||||
os << ", 0\n %";
|
||||
os << unaryInst->getName() << " = zext i1 %tmp_not_" << unaryInst->getName() << " to i32";
|
||||
os << '\n';
|
||||
|
||||
// 检查当前指令是否是终结指令
|
||||
if (inst->isTerminator()) {
|
||||
reachedTerminator = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
os << *inst << '\n';
|
||||
|
||||
// 检查当前指令是否是终结指令
|
||||
if (inst->isTerminator()) {
|
||||
reachedTerminator = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -619,10 +652,11 @@ void UnaryInst::print(std::ostream &os) const {
|
||||
printOperand(os, getOperand());
|
||||
break;
|
||||
case kNot:
|
||||
// 在BasicBlock::print中特殊处理整数逻辑非,这里不应该执行到
|
||||
os << "xor " << *getOperand()->getType() << " ";
|
||||
printOperand(os, getOperand());
|
||||
os << ", -1";
|
||||
return;
|
||||
break;
|
||||
case kFNot:
|
||||
os << "fcmp une " << *getOperand()->getType() << " ";
|
||||
printOperand(os, getOperand());
|
||||
@@ -698,8 +732,41 @@ void UncondBrInst::print(std::ostream &os) const {
|
||||
}
|
||||
|
||||
void CondBrInst::print(std::ostream &os) const {
|
||||
os << "br i1 "; // 条件分支的条件总是假定为i1类型
|
||||
printOperand(os, getCondition());
|
||||
Value* condition = getCondition();
|
||||
|
||||
// 检查条件是否来自比较指令
|
||||
if (auto* binaryInst = dynamic_cast<BinaryInst*>(condition)) {
|
||||
auto kind = binaryInst->getKind();
|
||||
if (kind == kICmpEQ || kind == kICmpNE || kind == kICmpLT ||
|
||||
kind == kICmpGT || kind == kICmpLE || kind == kICmpGE ||
|
||||
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 << ", label %";
|
||||
printBlockName(os, getThenBlock());
|
||||
os << ", label %";
|
||||
@@ -731,12 +798,19 @@ void LoadInst::print(std::ostream &os) const {
|
||||
}
|
||||
|
||||
void MemsetInst::print(std::ostream &os) const {
|
||||
os << "call void @llvm.memset.p0i8.i32(i8* ";
|
||||
printOperand(os, getPointer());
|
||||
os << ", i8 ";
|
||||
printOperand(os, getValue()); // value
|
||||
Value* ptr = getPointer();
|
||||
|
||||
// Generate a temporary bitcast instruction before the memset call
|
||||
// This is done at print time to avoid modifying the IR structure
|
||||
os << "%tmp_bitcast_" << ptr->getName() << " = bitcast " << *ptr->getType() << " ";
|
||||
printOperand(os, ptr);
|
||||
os << " to i8*\n ";
|
||||
|
||||
// Now call memset with the bitcast result
|
||||
os << "call void @llvm.memset.p0i8.i32(i8* %tmp_bitcast_" << ptr->getName() << ", i8 ";
|
||||
printOperand(os, getValue());
|
||||
os << ", i32 ";
|
||||
printOperand(os, getSize()); // size
|
||||
printOperand(os, getSize());
|
||||
os << ", i1 false)";
|
||||
}
|
||||
|
||||
@@ -1064,7 +1138,18 @@ void renameValues(Function* function) {
|
||||
|
||||
// 重命名指令
|
||||
for (auto& block : function->getBasicBlocks()) {
|
||||
bool reachedTerminator = false;
|
||||
for (auto& inst : block->getInstructions()) {
|
||||
// 跳过终结指令后的死代码
|
||||
if (reachedTerminator) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 检查当前指令是否是终结指令
|
||||
if (inst->isTerminator()) {
|
||||
reachedTerminator = true;
|
||||
}
|
||||
|
||||
// 只有产生值的指令需要重命名
|
||||
if (!inst->getType()->isVoid() && needsRename(inst->getName())) {
|
||||
valueNames[inst.get()] = "%" + std::to_string(tempCounter++);
|
||||
@@ -1130,6 +1215,9 @@ void Module::print(std::ostream& os) const {
|
||||
os << ")\n";
|
||||
}
|
||||
|
||||
// Always declare memset intrinsic when needed
|
||||
os << "declare void @llvm.memset.p0i8.i32(i8*, i8, i32, i1)\n";
|
||||
|
||||
if (!getExternalFunctions().empty()) {
|
||||
os << "\n"; // 外部函数和普通函数之间加空行
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user