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 ----