From 8763c0a11a330485e81492e10d501a4aa4fb2c3a Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Sun, 17 Aug 2025 01:35:03 +0800 Subject: [PATCH] =?UTF-8?q?[midend-LICM][fix]=E4=BF=AE=E6=94=B9=E8=AE=A1?= =?UTF-8?q?=E7=AE=97=E5=BE=AA=E7=8E=AF=E4=B8=8D=E5=8F=98=E9=87=8F=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E5=85=B3=E7=B3=BB=E7=9A=84=E6=8E=92=E5=BA=8F=E9=94=99?= =?UTF-8?q?=E8=AF=AF=EF=BC=8C=E4=BD=86=E6=98=AF=E5=BC=95=E5=85=A5=E4=BA=86?= =?UTF-8?q?=E5=BE=88=E5=A4=9ASegmentation=20fault=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/midend/Pass/Optimize/LICM.cpp | 173 ++++++++++++++++++++++++++++-- 1 file changed, 162 insertions(+), 11 deletions(-) diff --git a/src/midend/Pass/Optimize/LICM.cpp b/src/midend/Pass/Optimize/LICM.cpp index 3193dd3..6aef11d 100644 --- a/src/midend/Pass/Optimize/LICM.cpp +++ b/src/midend/Pass/Optimize/LICM.cpp @@ -18,38 +18,100 @@ bool LICMContext::hoistInstructions() { // 1. 先收集所有可外提指令 std::unordered_set workSet(chars->invariantInsts.begin(), chars->invariantInsts.end()); + if (DEBUG) { + std::cout << "LICM: Found " << workSet.size() << " candidate invariant instructions to hoist:" << std::endl; + for (auto *inst : workSet) { + std::cout << " - " << inst->getName() << " (kind: " << static_cast(inst->getKind()) + << ", in BB: " << inst->getParent()->getName() << ")" << std::endl; + } + } + // 2. 计算每个指令被依赖的次数(入度) std::unordered_map indegree; + std::unordered_map> dependencies; // 记录依赖关系 + std::unordered_map> dependents; // 记录被依赖关系 + for (auto *inst : workSet) { indegree[inst] = 0; + dependencies[inst] = {}; + dependents[inst] = {}; } + + if (DEBUG) { + std::cout << "LICM: Analyzing dependencies between invariant instructions..." << std::endl; + } + 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]++; + dependencies[inst].push_back(dep); + dependents[dep].push_back(inst); + + if (DEBUG) { + std::cout << " Dependency: " << inst->getName() << " depends on " << dep->getName() << std::endl; + } } } } } + if (DEBUG) { + std::cout << "LICM: Initial indegree analysis:" << std::endl; + for (auto &[inst, deg] : indegree) { + std::cout << " " << inst->getName() << ": indegree=" << deg; + if (deg > 0) { + std::cout << ", depends on: "; + for (auto *dep : dependencies[inst]) { + std::cout << dep->getName() << " "; + } + } + std::cout << std::endl; + } + } + // 3. Kahn拓扑排序 std::vector sorted; std::queue q; - for (auto &[inst, deg] : indegree) { - if (deg == 0) - q.push(inst); + + if (DEBUG) { + std::cout << "LICM: Starting topological sort..." << std::endl; } + + for (auto &[inst, deg] : indegree) { + if (deg == 0) { + q.push(inst); + if (DEBUG) { + std::cout << " Initial zero-indegree instruction: " << inst->getName() << std::endl; + } + } + } + + int sortStep = 0; 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 (DEBUG) { + std::cout << " Step " << (++sortStep) << ": Processing " << inst->getName() << std::endl; + } + + if (DEBUG) { + std::cout << " Reducing indegree of dependents of " << inst->getName() << std::endl; + } + + // 正确的拓扑排序:当处理一个指令时,应该减少其所有使用者(dependents)的入度 + for (auto *dependent : dependents[inst]) { + indegree[dependent]--; + if (DEBUG) { + std::cout << " Reducing indegree of " << dependent->getName() << " to " << indegree[dependent] << std::endl; + } + if (indegree[dependent] == 0) { + q.push(dependent); + if (DEBUG) { + std::cout << " Adding " << dependent->getName() << " to queue (indegree=0)" << std::endl; } } } @@ -58,23 +120,112 @@ bool LICMContext::hoistInstructions() { // 检查是否全部排序,若未全部排序,打印错误信息 // 这可能是因为存在循环依赖或其他问题导致无法完成拓扑排序 if (sorted.size() != workSet.size()) { - if (DEBUG) - std::cout << "LICM: Topological sort failed, possible dependency cycle." << std::endl; + if (DEBUG) { + std::cout << "LICM: Topological sort failed! Sorted " << sorted.size() + << " instructions out of " << workSet.size() << " total." << std::endl; + + // 找出未被排序的指令(形成循环依赖的指令) + std::unordered_set remaining; + for (auto *inst : workSet) { + bool found = false; + for (auto *sortedInst : sorted) { + if (inst == sortedInst) { + found = true; + break; + } + } + if (!found) { + remaining.insert(inst); + } + } + + std::cout << "LICM: Instructions involved in dependency cycle:" << std::endl; + for (auto *inst : remaining) { + std::cout << " - " << inst->getName() << " (indegree=" << indegree[inst] << ")" << std::endl; + std::cout << " Dependencies within cycle: "; + for (auto *dep : dependencies[inst]) { + if (remaining.count(dep)) { + std::cout << dep->getName() << " "; + } + } + std::cout << std::endl; + std::cout << " Dependents within cycle: "; + for (auto *dependent : dependents[inst]) { + if (remaining.count(dependent)) { + std::cout << dependent->getName() << " "; + } + } + std::cout << std::endl; + } + + // 尝试找出一个具体的循环路径 + std::cout << "LICM: Attempting to trace a dependency cycle:" << std::endl; + if (!remaining.empty()) { + auto *start = *remaining.begin(); + std::unordered_set visited; + std::vector path; + + std::function findCycle = [&](Instruction *current) -> bool { + if (visited.count(current)) { + // 找到环 + auto it = std::find(path.begin(), path.end(), current); + if (it != path.end()) { + std::cout << " Cycle found: "; + for (auto cycleIt = it; cycleIt != path.end(); ++cycleIt) { + std::cout << (*cycleIt)->getName() << " -> "; + } + std::cout << current->getName() << std::endl; + return true; + } + return false; + } + + visited.insert(current); + path.push_back(current); + + for (auto *dep : dependencies[current]) { + if (remaining.count(dep)) { + if (findCycle(dep)) { + return true; + } + } + } + + path.pop_back(); + return false; + }; + + findCycle(start); + } + } return false; } // 4. 按拓扑序外提 + if (DEBUG) { + std::cout << "LICM: Successfully completed topological sort. Hoisting instructions in order:" << std::endl; + } + for (auto *inst : sorted) { if (!inst) continue; BasicBlock *parent = inst->getParent(); if (parent && loop->contains(parent)) { + if (DEBUG) { + std::cout << " Hoisting " << 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); changed = true; } } + + if (DEBUG && changed) { + std::cout << "LICM: Successfully hoisted " << sorted.size() << " invariant instructions" << std::endl; + } + return changed; } // ---- LICM Pass Implementation ----