From baef82677bf285afeab778b92f9de4b8110861a2 Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Tue, 12 Aug 2025 16:18:00 +0800 Subject: [PATCH] =?UTF-8?q?[midend-LICM]=E5=B0=86=E8=83=BD=E5=A4=9F?= =?UTF-8?q?=E5=A4=96=E6=8F=90=E7=9A=84=E5=BE=AA=E7=8E=AF=E4=B8=8D=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E8=BF=9B=E8=A1=8CKanh=E6=8B=93=E6=89=91=E6=8E=92?= =?UTF-8?q?=E5=BA=8F=E4=BF=9D=E8=AF=81=E5=A4=96=E6=8F=90=E5=90=8E=E7=9A=84?= =?UTF-8?q?=E8=AE=A1=E7=AE=97=E9=A1=BA=E5=BA=8F=E6=AD=A3=E7=A1=AE=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/midend/Pass/Optimize/LICM.cpp | 76 +++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 24 deletions(-) diff --git a/src/midend/Pass/Optimize/LICM.cpp b/src/midend/Pass/Optimize/LICM.cpp index da9b432..b583066 100644 --- a/src/midend/Pass/Optimize/LICM.cpp +++ b/src/midend/Pass/Optimize/LICM.cpp @@ -12,33 +12,62 @@ bool LICMContext::run() { return hoistInstructions(); } bool LICMContext::hoistInstructions() { bool changed = false; BasicBlock *preheader = loop->getPreHeader(); - if (!preheader || !chars){ - if(DEBUG) { - std::cerr << "LICM: No preheader or loop characteristics found, skipping hoisting." << std::endl; + if (!preheader || !chars) + return false; + + // 1. 先收集所有可外提指令 + std::unordered_set workSet(chars->invariantInsts.begin(), chars->invariantInsts.end()); + + // 2. 计算每个指令被依赖的次数(入度) + std::unordered_map indegree; + for (auto *inst : workSet) { + indegree[inst] = 0; + } + for (auto *inst : workSet) { + for (size_t i = 0; i < inst->getNumOperands(); ++i) { + if (auto *dep = dynamic_cast(inst->getOperand(i))) { + if (workSet.count(dep)) { + indegree[inst]++; + } + } } + } + + // 3. Kahn拓扑排序 + std::vector sorted; + std::queue q; + for (auto &[inst, deg] : indegree) { + if (deg == 0) + q.push(inst); + } + while (!q.empty()) { + auto *inst = q.front(); + q.pop(); + sorted.push_back(inst); + for (size_t i = 0; i < inst->getNumOperands(); ++i) { + if (auto *dep = dynamic_cast(inst->getOperand(i))) { + if (workSet.count(dep)) { + indegree[dep]--; + if (indegree[dep] == 0) + q.push(dep); + } + } + } + } + + // 检查是否全部排序,若未全部排序,说明有环(理论上不会) + if (sorted.size() != workSet.size()) { + if (DEBUG) + std::cerr << "LICM: Topological sort failed, possible dependency cycle." << std::endl; return false; } - - for (auto *inst : chars->invariantInsts) { - if (!inst) { - if(DEBUG) { - std::cerr << "LICM: Invalid instruction found, skipping." << std::endl; - } - continue; // 跳过无效指令 - } - else{ - if(DEBUG) { - std::cout << "LICM: Processing instruction " << inst->getName() << " for hoisting." << std::endl; - } - } + + // 4. 按拓扑序外提 + for (auto *inst : sorted) { + if (!inst) + continue; BasicBlock *parent = inst->getParent(); - // 只外提当前还在循环体内的指令 if (parent && loop->contains(parent)) { - // 获取源和槽的迭代器并移动指令到前置块 - if(DEBUG) { - std::cout << "LICM: Hoisting instruction " << inst->getName() << " from " - << parent->getName() << " to preheader " << preheader->getName() << std::endl; - } auto sourcePos = parent->findInstIterator(inst); auto targetPos = preheader->terminator(); parent->moveInst(sourcePos, targetPos, preheader); @@ -47,7 +76,6 @@ bool LICMContext::hoistInstructions() { } return changed; } - // ---- LICM Pass Implementation ---- bool LICM::runOnFunction(Function *F, AnalysisManager &AM) { @@ -60,7 +88,7 @@ bool LICM::runOnFunction(Function *F, AnalysisManager &AM) { // 对每个函数内的所有循环做处理 for (const auto &loop_ptr : loopAnalysis->getAllLoops()) { Loop *loop = loop_ptr.get(); - if(DEBUG){ + if (DEBUG) { std::cout << "LICM: Processing loop in function " << F->getName() << ": " << loop->getName() << std::endl; } const LoopCharacteristics *chars = loopCharsResult->getCharacteristics(loop);