From e172678e1b4752a478c2227750f69a9d2310d45c Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Sun, 8 Mar 2026 18:28:21 +0300 Subject: [PATCH] fix freezing --- .../MoveOperators/move_operators.cpp | 193 +++++++++++++----- 1 file changed, 141 insertions(+), 52 deletions(-) diff --git a/src/Transformations/MoveOperators/move_operators.cpp b/src/Transformations/MoveOperators/move_operators.cpp index 60d36f8..f7c197e 100644 --- a/src/Transformations/MoveOperators/move_operators.cpp +++ b/src/Transformations/MoveOperators/move_operators.cpp @@ -808,6 +808,47 @@ static map> analyzeBasicBlockIntraDependencie return to_string((int)a->getType()) + "#" + to_string((int)a->getMemType()) + "#" + a->getValue(); }; + auto memKeyFromInstr = [&](const SAPFOR::Instruction* instr) -> string + { + if (!instr) + return string(); + SgExpression* ex = instr->getExpression(); + if (!ex || !ex->unparse()) + return string(); + auto normalizeExprText = [](const string& raw) -> string + { + string t; + t.reserve(raw.size()); + for (unsigned char c : raw) + if (!std::isspace(c)) + t.push_back((char)c); + + auto stripOneLayer = [](const string& x) -> string + { + if (x.size() < 2 || x.front() != '(' || x.back() != ')') + return x; + int bal = 0; + for (size_t i = 0; i + 1 < x.size(); ++i) + { + if (x[i] == '(') bal++; + else if (x[i] == ')') bal--; + if (bal == 0 && i + 1 < x.size() - 1) + return x; + } + return x.substr(1, x.size() - 2); + }; + while (true) + { + const string stripped = stripOneLayer(t); + if (stripped == t) + break; + t = stripped; + } + return t; + }; + return "MEMEX#" + normalizeExprText(ex->unparse()); + }; + auto isBarrier = [&](const SAPFOR::Instruction* instr) -> bool { if (!instr) @@ -816,8 +857,6 @@ static map> analyzeBasicBlockIntraDependencie switch (op) { case SAPFOR::CFG_OP::F_CALL: - case SAPFOR::CFG_OP::STORE: - case SAPFOR::CFG_OP::REC_REF_STORE: case SAPFOR::CFG_OP::IO_PARAM: case SAPFOR::CFG_OP::DVM_DIR: case SAPFOR::CFG_OP::SPF_DIR: @@ -847,6 +886,7 @@ static map> analyzeBasicBlockIntraDependencie // Reaching definitions inside the BasicBlock in straight-line order: // lastDef[var] = last operator in this block that defined it. map> lastDef; + map> lastMemDef; map> depsSets; for (auto* ir : bb->getInstructions()) @@ -856,7 +896,9 @@ static map> analyzeBasicBlockIntraDependencie const SAPFOR::Instruction* instr = ir->getInstruction(); SgStatement* opStmt = instr->getOperator(); - if (!opStmt || isCompoundStmt(opStmt)) + if (!opStmt) + continue; + if (isCompoundStmt(opStmt)) continue; if (isBarrier(instr)) @@ -869,6 +911,14 @@ static map> analyzeBasicBlockIntraDependencie else ++it; } + for (auto it = lastMemDef.begin(); it != lastMemDef.end();) + { + const SAPFOR::Argument* a = it->second.second; + if (!a || a->isMemGlobal() || a->isParameter()) + it = lastMemDef.erase(it); + else + ++it; + } } if (!result.count(opStmt)) @@ -878,18 +928,50 @@ static map> analyzeBasicBlockIntraDependencie { if (!isTrackable(use)) return; - auto it = lastDef.find(argKey(use)); + const string k = argKey(use); + auto it = lastDef.find(k); if (it == lastDef.end()) - return; // only deps inside this BB are needed + return; + if (it->second.first && it->second.first != opStmt) + depsSets[opStmt].insert(it->second.first); + }; + + auto addMemDep = [&](const string& key) + { + if (key.empty()) + return; + auto it = lastMemDef.find(key); + if (it == lastMemDef.end()) + return; if (it->second.first && it->second.first != opStmt) depsSets[opStmt].insert(it->second.first); }; addDep(instr->getArg1()); addDep(instr->getArg2()); + if (instr->getOperation() == SAPFOR::CFG_OP::STORE || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE) + addDep(instr->getResult()); + + if (instr->getOperation() == SAPFOR::CFG_OP::LOAD || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_LOAD) + { + const string memKey = memKeyFromInstr(instr); + addMemDep(memKey); + } if (isDef(instr)) - lastDef[argKey(instr->getResult())] = { opStmt, instr->getResult() }; + { + const string dk = argKey(instr->getResult()); + lastDef[dk] = { opStmt, instr->getResult() }; + } + + if (instr->getOperation() == SAPFOR::CFG_OP::STORE || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE) + { + const string k = memKeyFromInstr(instr); + SAPFOR::Argument* base = instr->getArg1(); + if (!k.empty() && base) + lastMemDef[k] = { opStmt, base }; + addMemDep(k); + } } for (auto& kv : result) @@ -961,8 +1043,11 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb) SgStatement* scan = parent->lexNext(); SgStatement* end = lastNode; bool found = false; + set visited; while (scan && scan != end) { + if (!visited.insert(scan).second) + return false; if (scan == ops.front()) { found = true; @@ -977,14 +1062,9 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb) while (cur && cur != lastNode && idx < ops.size()) { if (cur == ops[idx]) - { ++idx; - } - else - { - if (isSgExecutableStatement(cur) && !opSet.count(cur)) - return false; - } + else if (isSgExecutableStatement(cur) && !opSet.count(cur)) + return false; if (idx == ops.size()) break; cur = cur->lexNext(); @@ -998,50 +1078,59 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb) const auto depsMap = analyzeBasicBlockIntraDependencies(bb); vector order = ops; - map pos; - for (int i = 0; i < (int)order.size(); ++i) - pos[order[i]] = i; - - for (int i = 0; i < (int)order.size(); ++i) + auto buildPos = [&](const vector& v) { - SgStatement* cur = order[i]; - auto it = depsMap.find(cur); - if (it == depsMap.end() || it->second.empty()) - continue; + map pos; + for (int i = 0; i < (int)v.size(); ++i) + pos[v[i]] = i; + return pos; + }; - int lastDepIdx = -1; - for (SgStatement* dep : it->second) + const int maxIterations = (int)order.size() * (int)order.size() + 10; + bool anyMove = false; + for (int iter = 0; iter < maxIterations; ++iter) + { + bool movedThisIter = false; + const auto pos = buildPos(order); + + for (int i = 0; i < (int)order.size(); ++i) { - auto itP = pos.find(dep); - if (itP != pos.end()) - lastDepIdx = max(lastDepIdx, itP->second); + SgStatement* curSt = order[i]; + auto it = depsMap.find(curSt); + if (it == depsMap.end() || it->second.empty()) + continue; + + int lastDepIdx = -1; + for (SgStatement* dep : it->second) + { + auto itP = pos.find(dep); + if (itP != pos.end()) + lastDepIdx = max(lastDepIdx, itP->second); + } + if (lastDepIdx < 0) + continue; + + int target = lastDepIdx + 1; + if (target == i) + continue; + + SgStatement* moved = order[i]; + order.erase(order.begin() + i); + if (target > i) + target -= 1; + if (target < 0) + target = 0; + if (target > (int)order.size()) + target = (int)order.size(); + order.insert(order.begin() + target, moved); + + movedThisIter = true; + anyMove = true; + break; } - if (lastDepIdx < 0) - continue; - - const int target = lastDepIdx + 1; - if (target == i) - continue; - - SgStatement* moved = order[i]; - order.erase(order.begin() + i); - - int insertIdx = target; - if (target > i) - insertIdx = target - 1; - if (insertIdx < 0) - insertIdx = 0; - if (insertIdx > (int)order.size()) - insertIdx = (int)order.size(); - - order.insert(order.begin() + insertIdx, moved); - - pos.clear(); - for (int k = 0; k < (int)order.size(); ++k) - pos[order[k]] = k; - - i = max(-1, min(i, insertIdx) - 1); + if (!movedThisIter) + break; } bool changed = false;