#include "TailCallOpt.h" #include "IR.h" #include "IRBuilder.h" #include "SysYIROptUtils.h" #include // #include #include namespace sysy { void *TailCallOpt::ID = (void *)&TailCallOpt::ID; void TailCallOpt::getAnalysisUsage(std::set &analysisDependencies, std::set &analysisInvalidations) const { analysisInvalidations.insert(&DominatorTreeAnalysisPass::ID); analysisInvalidations.insert(&LoopAnalysisPass::ID); } bool TailCallOpt::runOnFunction(Function *F, AnalysisManager &AM) { std::vector tailCallInsts; // 遍历函数的所有基本块 for (auto &bb_ptr : F->getBasicBlocks()) { auto BB = bb_ptr.get(); if (BB->getInstructions().empty()) continue; // 跳过空基本块 auto term_iter = BB->terminator(); if (term_iter == BB->getInstructions().end()) continue; // 没有终结指令则跳过 auto term = (*term_iter).get(); if (!term || !term->isReturn()) continue; // 不是返回指令则跳过 auto retInst = static_cast(term); Instruction *prevInst = nullptr; if (BB->getInstructions().size() > 1) { auto it = term_iter; --it; // 获取返回指令前的指令 prevInst = (*it).get(); } if (!prevInst || !prevInst->isCall()) continue; // 前一条不是调用指令则跳过 auto callInst = static_cast(prevInst); // 检查是否为尾递归调用:被调用函数与当前函数相同且返回值与调用结果匹配 if (callInst->getCallee() == F) { // 对于尾递归,返回值应为调用结果或为 void 类型 if (retInst->getReturnValue() == callInst || (retInst->getReturnValue() == nullptr && callInst->getType()->isVoid())) { tailCallInsts.push_back(callInst); } } } if (tailCallInsts.empty()) { return false; } // 创建一个新的入口基本块,作为循环的前置块 auto original_entry = F->getEntryBlock(); auto new_entry = F->addBasicBlock("tco.entry." + F->getName()); auto loop_header = F->addBasicBlock("tco.loop_header." + F->getName()); // 将原入口块中的所有指令移动到循环头块 loop_header->getInstructions().splice(loop_header->end(), original_entry->getInstructions()); original_entry->setName("tco.pre_header"); // 为函数参数创建 phi 节点 builder->setPosition(loop_header, loop_header->begin()); std::vector phis; auto original_args = F->getArguments(); for (auto &arg : original_args) { auto phi = builder->createPhiInst(arg->getType(), {}, {}, "tco.phi."+arg->getName()); phis.push_back(phi); } // 用 phi 节点替换所有原始参数的使用 for (size_t i = 0; i < original_args.size(); ++i) { original_args[i]->replaceAllUsesWith(phis[i]); } // 设置 phi 节点的输入值 for (size_t i = 0; i < phis.size(); ++i) { phis[i]->addIncoming(original_args[i], new_entry); } // 连接各个基本块 builder->setPosition(original_entry, original_entry->end()); builder->createUncondBrInst(new_entry); original_entry->addSuccessor(new_entry); builder->setPosition(new_entry, new_entry->end()); builder->createUncondBrInst(loop_header); new_entry->addSuccessor(loop_header); loop_header->addPredecessor(new_entry); // 处理每一个尾递归调用 for (auto callInst : tailCallInsts) { auto tail_call_block = callInst->getParent(); // 收集尾递归调用的参数 auto args_range = callInst->getArguments(); std::vector args; std::transform(args_range.begin(), args_range.end(), std::back_inserter(args), [](auto& use_ptr){ return use_ptr->getValue(); }); // 用新的参数值更新 phi 节点 for (size_t i = 0; i < phis.size(); ++i) { phis[i]->addIncoming(args[i], tail_call_block); } // 移除原有的调用和返回指令 auto term_iter = tail_call_block->terminator(); SysYIROptUtils::usedelete(term_iter); auto call_iter = tail_call_block->findInstIterator(callInst); SysYIROptUtils::usedelete(call_iter); // 添加跳转回循环头块的分支指令 builder->setPosition(tail_call_block, tail_call_block->end()); builder->createUncondBrInst(loop_header); tail_call_block->addSuccessor(loop_header); loop_header->addPredecessor(tail_call_block); } return true; } } // namespace sysy