From f62bfc8e8bb3baa741ee3f79abd4bd480e87a4ce Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Wed, 1 Apr 2026 17:12:20 +0300 Subject: [PATCH 1/5] change reordering logic --- .../MoveOperators/move_operators.cpp | 52 ++++++++++++++----- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/src/Transformations/MoveOperators/move_operators.cpp b/src/Transformations/MoveOperators/move_operators.cpp index 0793913..c68a9c4 100644 --- a/src/Transformations/MoveOperators/move_operators.cpp +++ b/src/Transformations/MoveOperators/move_operators.cpp @@ -470,6 +470,8 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb, const // as close as possible after its last dependency (if any). const auto depsMap = analyzeBasicBlockIntraDependencies(bb); vector order = ops; + const vector originalOrder = ops; + const int nOrig = (int)originalOrder.size(); auto indexIn = [](const vector& v, SgStatement* s) -> int { @@ -479,37 +481,59 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb, const return -1; }; + auto indexInOriginal = [&](SgStatement* s) -> int + { + return indexIn(originalOrder, s); + }; + for (SgStatement* s : ops) { auto itDeps = depsMap.find(s); if (itDeps == depsMap.end() || itDeps->second.empty()) continue; + int lastDepOrigIdx = -1; + for (SgStatement* dep : itDeps->second) + { + const int j = indexInOriginal(dep); + if (j >= 0) + lastDepOrigIdx = max(lastDepOrigIdx, j); + } + if (lastDepOrigIdx < 0) + continue; + + SgStatement* successor = nullptr; + if (lastDepOrigIdx + 1 < nOrig) + successor = originalOrder[lastDepOrigIdx + 1]; + int posS = indexIn(order, s); if (posS < 0) continue; - int lastDepIdx = -1; - for (SgStatement* dep : itDeps->second) + if (successor == nullptr) { - const int j = indexIn(order, dep); - if (j >= 0) - lastDepIdx = max(lastDepIdx, j); + if (posS == (int)order.size() - 1) + continue; + order.erase(order.begin() + posS); + order.push_back(s); + continue; } - if (lastDepIdx < 0) + + if (successor == s) continue; - if (posS == lastDepIdx + 1) + const int posSucc = indexIn(order, successor); + if (posSucc < 0) + continue; + + if (posS + 1 == posSucc) continue; order.erase(order.begin() + posS); - - int lp = lastDepIdx; - if (posS < lastDepIdx) - lp = lastDepIdx - 1; - - const int insertAt = lp + 1; - order.insert(order.begin() + insertAt, s); + const int posSucc2 = indexIn(order, successor); + if (posSucc2 < 0) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + order.insert(order.begin() + posSucc2, s); } bool changed = false; -- 2.49.1 From f02ffe45f5e756f28b7a6e81bfc9f1a77dddac56 Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Thu, 23 Apr 2026 16:41:42 +0300 Subject: [PATCH 2/5] some fixes with finding dependencies between operators --- .../MoveOperators/move_operators.cpp | 537 ++++++++++++------ 1 file changed, 377 insertions(+), 160 deletions(-) diff --git a/src/Transformations/MoveOperators/move_operators.cpp b/src/Transformations/MoveOperators/move_operators.cpp index c68a9c4..bc9b1e5 100644 --- a/src/Transformations/MoveOperators/move_operators.cpp +++ b/src/Transformations/MoveOperators/move_operators.cpp @@ -5,6 +5,9 @@ #include #include #include +#include +#include +#include #include "../../Utils/errors.h" #include "../../Utils/SgUtils.h" @@ -21,6 +24,147 @@ set loop_tags = {FOR_NODE}; set control_tags = {IF_NODE, ELSEIF_NODE, DO_WHILE_NODE, WHILE_NODE, LOGIF_NODE}; set control_end_tags = {CONTROL_END}; +namespace +{ +enum class ArrayIndexCompareResult +{ + Equal, + NotEqual, + Unknown +}; + +// Structural key for array index / subscript analysis (stable across LOAD/STORE of the same access). +string buildStructuralExprKey(SgExpression* e) +{ + if (!e) + return string("_"); + + if (auto* ar = isSgArrayRefExp(e)) + { + SgSymbol* sym = ar->symbol() ? OriginalSymbol(ar->symbol()) : nullptr; + string key = string("A(") + (sym ? sym->identifier() : "?"); + const int n = ar->numberOfSubscripts(); + for (int i = 0; i < n; ++i) + { + key += ","; + key += buildStructuralExprKey(ar->subscript(i)); + } + key += ")"; + return key; + } + + if (e->variant() == VAR_REF || e->variant() == CONST_REF) + { + SgSymbol* sym = e->symbol() ? OriginalSymbol(e->symbol()) : nullptr; + return string((e->variant() == VAR_REF) ? "V(" : "C(") + (sym ? sym->identifier() : "?") + ")"; + } + + if (auto* v = isSgValueExp(e)) + { + if (e->variant() == INT_VAL) + return string("I(") + to_string(v->intValue()) + ")"; + if (e->variant() == BOOL_VAL) + return string("B(") + (v->boolValue() ? "1" : "0") + ")"; + if (e->variant() == CHAR_VAL) + return string("CH(") + string(1, v->charValue()) + ")"; + if (e->variant() == FLOAT_VAL) + { + char* fv = v->floatValue(); + return string("F(") + (fv ? string(fv) : string()) + ")"; + } + if (e->variant() == DOUBLE_VAL) + { + char* dv = v->doubleValue(); + if (!dv || !*dv) + return string("D()"); + char* endp = nullptr; + const double d = strtod(dv, &endp); + if (endp != dv && std::isfinite(d)) + { + const double r = std::round(d); + if (std::fabs(d - r) < 1e-12 && r >= static_cast(INT_MIN) && r <= static_cast(INT_MAX)) + return string("I(") + to_string(static_cast(r)) + ")"; + } + return string("D(") + string(dv) + ")"; + } + if (e->variant() == STRING_VAL) + return string("S(") + (v->stringValue() ? v->stringValue() : string()) + ")"; + } + + if (e->variant() == MULT_OP && e->lhs() && e->rhs()) + { + string a = buildStructuralExprKey(e->lhs()); + string b = buildStructuralExprKey(e->rhs()); + if (a > b) + swap(a, b); + return string("N(") + to_string(e->variant()) + ",L=" + a + ",R=" + b + ")"; + } + + string key = string("N(") + to_string(e->variant()); + if (e->lhs()) + key += ",L=" + buildStructuralExprKey(e->lhs()); + if (e->rhs()) + key += ",R=" + buildStructuralExprKey(e->rhs()); + key += ")"; + return key; +} + +// Prefer AST from IR instruction (same SgArrayRef for matching store/load); fallback to idxStack string. +string memexKeyForArrayLoadStore(const SAPFOR::Instruction* instr, const function& irStackKey) +{ + if (!instr) + return string(); + SgExpression* ex = instr->getExpression(); + if (ex) + { + if (isSgArrayRefExp(ex)) + return string("MEMEX#") + buildStructuralExprKey(ex); + return string("MEMEX#") + buildStructuralExprKey(ex); + } + return irStackKey(); +} + +ArrayIndexCompareResult compareIndexExpressions(SgExpression* a, SgExpression* b) +{ + if (!a && !b) + return ArrayIndexCompareResult::Equal; + if (!a || !b) + return ArrayIndexCompareResult::NotEqual; + const string ka = buildStructuralExprKey(a); + const string kb = buildStructuralExprKey(b); + if (ka.empty() || kb.empty()) + return ArrayIndexCompareResult::Unknown; + if (ka == kb) + return ArrayIndexCompareResult::Equal; + return ArrayIndexCompareResult::NotEqual; +} + +ArrayIndexCompareResult compareArrayRefExpressions(SgArrayRefExp* a, SgArrayRefExp* b) +{ + if (!a && !b) + return ArrayIndexCompareResult::Equal; + if (!a || !b) + return ArrayIndexCompareResult::NotEqual; + SgSymbol* s1 = a->symbol() ? OriginalSymbol(a->symbol()) : nullptr; + SgSymbol* s2 = b->symbol() ? OriginalSymbol(b->symbol()) : nullptr; + if (s1 && s2) + { + if (strcmp(s1->identifier(), s2->identifier()) != 0) + return ArrayIndexCompareResult::NotEqual; + } + else if (s1 != s2) + return ArrayIndexCompareResult::NotEqual; + if (a->numberOfSubscripts() != b->numberOfSubscripts()) + return ArrayIndexCompareResult::NotEqual; + for (int i = 0; i < a->numberOfSubscripts(); ++i) + { + ArrayIndexCompareResult c = compareIndexExpressions(a->subscript(i), b->subscript(i)); + if (c != ArrayIndexCompareResult::Equal) + return c; + } + return ArrayIndexCompareResult::Equal; +} +} // namespace static vector findInstructionsFromStatement(SgStatement* st, const vector& blocks) { @@ -151,83 +295,39 @@ static map> analyzeBasicBlockIntraDependencie return loop_tags.count(v) || control_tags.count(v) || control_end_tags.count(v); }; - auto isTrackable = [](const SAPFOR::Argument* a) -> bool + auto isVarArg = [](const SAPFOR::Argument* a) -> bool + { + return a && a->getType() == SAPFOR::CFG_ARG_TYPE::VAR; + }; + + auto isArrayArg = [](const SAPFOR::Argument* a) -> bool + { + return a && a->getType() == SAPFOR::CFG_ARG_TYPE::ARRAY; + }; + + auto varKey = [&](const SAPFOR::Argument* a) -> string { if (!a) + return string(); + return a->getValue(); + }; + + auto parseIntConst = [](const SAPFOR::Argument* a, int& out) -> bool + { + if (!a || a->getType() != SAPFOR::CFG_ARG_TYPE::CONST) return false; - const auto t = a->getType(); - return t == SAPFOR::CFG_ARG_TYPE::VAR || t == SAPFOR::CFG_ARG_TYPE::REG; - }; - - auto argKey = [&](const SAPFOR::Argument* a) -> string - { - if (!a) - return string(); - 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) - return string(); - - auto exprKey = [&](auto&& self, SgExpression* e) -> string + try { - if (!e) - return string("_"); - - if (auto* ar = isSgArrayRefExp(e)) - { - SgSymbol* sym = ar->symbol() ? OriginalSymbol(ar->symbol()) : nullptr; - string key = string("A(") + (sym ? sym->identifier() : "?"); - const int n = ar->numberOfSubscripts(); - for (int i = 0; i < n; ++i) - { - key += ","; - key += self(self, ar->subscript(i)); - } - key += ")"; - return key; - } - - if (e->variant() == VAR_REF || e->variant() == CONST_REF) - { - SgSymbol* sym = e->symbol() ? OriginalSymbol(e->symbol()) : nullptr; - return string((e->variant() == VAR_REF) ? "V(" : "C(") + (sym ? sym->identifier() : "?") + ")"; - } - - if (auto* v = isSgValueExp(e)) - { - if (e->variant() == INT_VAL) - return string("I(") + to_string(v->intValue()) + ")"; - if (e->variant() == BOOL_VAL) - return string("B(") + (v->boolValue() ? "1" : "0") + ")"; - if (e->variant() == CHAR_VAL) - return string("CH(") + string(1, v->charValue()) + ")"; - if (e->variant() == FLOAT_VAL) - return string("F(") + (v->floatValue() ? v->floatValue() : "") + ")"; - if (e->variant() == DOUBLE_VAL) - return string("D(") + (v->doubleValue() ? v->doubleValue() : "") + ")"; - if (e->variant() == STRING_VAL) - return string("S(") + (v->stringValue() ? v->stringValue() : "") + ")"; - } - - string key = string("N(") + to_string(e->variant()); - if (e->lhs()) - key += ",L=" + self(self, e->lhs()); - if (e->rhs()) - key += ",R=" + self(self, e->rhs()); - key += ")"; - return key; - }; - - return "MEMEX#" + exprKey(exprKey, ex); + out = stoi(a->getValue()); + return true; + } + catch (...) + { + return false; + } }; - auto isBarrier = [&](const SAPFOR::Instruction* instr) -> bool + auto isBarrierInstr = [&](const SAPFOR::Instruction* instr) -> bool { if (!instr) return true; @@ -246,112 +346,229 @@ static map> analyzeBasicBlockIntraDependencie } }; - auto isDef = [&](const SAPFOR::Instruction* instr) -> bool - { - if (!instr) - return false; - SAPFOR::Argument* r = instr->getResult(); - if (!isTrackable(r)) - return false; - - const auto op = instr->getOperation(); - if (op == SAPFOR::CFG_OP::STORE || op == SAPFOR::CFG_OP::REC_REF_STORE) - return false; - - return true; - }; - - // Reaching definitions inside the BasicBlock in straight-line order: - // lastDef[var] = last operator in this block that defined it. - map> lastDef; - map> lastMemDef; + map lastDef; + map lastMemDef; map> depsSets; - for (auto* ir : bb->getInstructions()) + const auto& irs = bb->getInstructions(); + size_t i = 0; + while (i < irs.size()) { + auto* ir = irs[i]; if (!ir || !ir->getInstruction()) - continue; - - const SAPFOR::Instruction* instr = ir->getInstruction(); - SgStatement* opStmt = instr->getOperator(); - if (!opStmt) - continue; - if (isCompoundStmt(opStmt)) - continue; - - if (isBarrier(instr)) { - for (auto it = lastDef.begin(); it != lastDef.end();) - { - const SAPFOR::Argument* a = it->second.second; - if (!a || a->isMemGlobal() || a->isParameter()) - it = lastDef.erase(it); - 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; - } + ++i; + continue; } - if (!result.count(opStmt)) - result[opStmt] = {}; - - auto addDep = [&](SAPFOR::Argument* use) + const SAPFOR::Instruction* firstInstr = ir->getInstruction(); + SgStatement* stmt = firstInstr->getOperator(); + if (!stmt || isCompoundStmt(stmt)) { - if (!isTrackable(use)) - return; - const string k = argKey(use); - auto it = lastDef.find(k); - if (it == lastDef.end()) - return; - if (it->second.first && it->second.first != opStmt) - depsSets[opStmt].insert(it->second.first); + ++i; + continue; + } + + vector group; + group.reserve(8); + bool isBarrierStmt = false; + + while (i < irs.size()) + { + auto* ir2 = irs[i]; + if (!ir2 || !ir2->getInstruction()) + { + ++i; + continue; + } + + const SAPFOR::Instruction* instr = ir2->getInstruction(); + if (instr->getOperator() != stmt) + break; + + group.push_back(instr); + if (isBarrierInstr(instr)) + isBarrierStmt = true; + ++i; + } + + if (!result.count(stmt)) + result[stmt] = {}; + + set usesVars; + set defsVars; + set usesMem; + set defsMem; + + vector idxStack; + idxStack.reserve(8); + + auto idxAtom = [&](const SAPFOR::Argument* a) -> string + { + if (!a) + return string(); + const auto t = a->getType(); + if (t == SAPFOR::CFG_ARG_TYPE::VAR || t == SAPFOR::CFG_ARG_TYPE::CONST || t == SAPFOR::CFG_ARG_TYPE::CONST_STR) + return a->getValue(); + return string("*"); }; - auto addMemDep = [&](const string& key) + auto joinIdx = [&](const vector& idx) -> string { - 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); + string s; + for (size_t k = 0; k < idx.size(); ++k) + { + if (k) + s += ","; + s += idx[k]; + } + return s; }; - addDep(instr->getArg1()); - addDep(instr->getArg2()); - if (instr->getOperation() == SAPFOR::CFG_OP::RANGE) - addDep(instr->getResult()); - - 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) + auto popLastIdx = [&](int cnt) -> vector { - const string memKey = memKeyFromInstr(instr); - addMemDep(memKey); - } + vector idx; + if (cnt <= 0 || (size_t)cnt > idxStack.size()) + return idx; + idx.assign(idxStack.end() - cnt, idxStack.end()); + idxStack.erase(idxStack.end() - cnt, idxStack.end()); + return idx; + }; - if (isDef(instr)) + auto memKeyFromLoadStore = [&](const SAPFOR::Instruction* instr) -> string { - 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); + if (!instr) + return string(); SAPFOR::Argument* base = instr->getArg1(); - if (!k.empty() && base) - lastMemDef[k] = { opStmt, base }; - addMemDep(k); + if (!isArrayArg(base)) + return string(); + + int cnt = 0; + if (!parseIntConst(instr->getArg2(), cnt)) + cnt = 0; + const auto idx = popLastIdx(cnt); + return base->getValue() + "[" + joinIdx(idx) + "]"; + }; + + string lastStoreKey; + string lastScalarDefKey; + + for (auto* instr : group) + { + if (!instr) + continue; + + if (isVarArg(instr->getArg1())) + usesVars.insert(varKey(instr->getArg1())); + if (isVarArg(instr->getArg2())) + usesVars.insert(varKey(instr->getArg2())); + + if (instr->getOperation() == SAPFOR::CFG_OP::RANGE && isVarArg(instr->getResult())) + usesVars.insert(varKey(instr->getResult())); + + if ((instr->getOperation() == SAPFOR::CFG_OP::STORE || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE) && + isVarArg(instr->getResult())) + { + usesVars.insert(varKey(instr->getResult())); + } + + if (instr->getOperation() == SAPFOR::CFG_OP::REF) + { + idxStack.push_back(idxAtom(instr->getArg1())); + } + else if (instr->getOperation() == SAPFOR::CFG_OP::RANGE) + { + idxStack.push_back(idxAtom(instr->getArg1()) + ":" + idxAtom(instr->getArg2()) + ":" + idxAtom(instr->getResult())); + } + else if (instr->getOperation() == SAPFOR::CFG_OP::LOAD || instr->getOperation() == SAPFOR::CFG_OP::STORE) + { + int dimCnt = 0; + if (!parseIntConst(instr->getArg2(), dimCnt)) + dimCnt = 0; + + string k; + if (instr->getExpression()) + { + k = memexKeyForArrayLoadStore(instr, []() { return string(); }); + if (!k.empty()) + popLastIdx(dimCnt); + } + if (k.empty()) + k = memKeyFromLoadStore(instr); + + if (!k.empty()) + { + if (instr->getOperation() == SAPFOR::CFG_OP::LOAD) + usesMem.insert(k); + else + { + defsMem.insert(k); + lastStoreKey = k; + } + } + } + else if (instr->getOperation() == SAPFOR::CFG_OP::REC_REF_LOAD || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE) + { + SAPFOR::Argument* base = instr->getArg1(); + if (base && (base->getType() == SAPFOR::CFG_ARG_TYPE::RECORD || base->getType() == SAPFOR::CFG_ARG_TYPE::VAR)) + { + const string k = base->getValue(); + if (instr->getOperation() == SAPFOR::CFG_OP::REC_REF_LOAD) + usesMem.insert(k); + else + { + defsMem.insert(k); + lastStoreKey = k; + } + } + } + } + + if (!group.empty()) + { + const SAPFOR::Instruction* last = group.back(); + if (last && last->getOperation() == SAPFOR::CFG_OP::ASSIGN && isVarArg(last->getResult())) + { + lastScalarDefKey = varKey(last->getResult()); + defsVars.insert(lastScalarDefKey); + } + else if (last && (last->getOperation() == SAPFOR::CFG_OP::STORE || last->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE)) + { + if (!lastStoreKey.empty()) + defsMem.insert(lastStoreKey); + } + } + + auto addDepFromMap = [&](const map& m, const string& k) + { + auto it = m.find(k); + if (it == m.end()) + return; + if (it->second && it->second != stmt) + depsSets[stmt].insert(it->second); + }; + + for (const auto& k : usesVars) + addDepFromMap(lastDef, k); + for (const auto& k : usesMem) + addDepFromMap(lastMemDef, k); + + if (isBarrierStmt) + { + lastDef.clear(); + lastMemDef.clear(); + continue; + } + + for (const auto& k : defsVars) + { + addDepFromMap(lastDef, k); + lastDef[k] = stmt; + } + for (const auto& k : defsMem) + { + addDepFromMap(lastMemDef, k); + lastMemDef[k] = stmt; } } -- 2.49.1 From 62e996f2e21c2e27f78c85879dafb3c862c86b87 Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Tue, 5 May 2026 15:50:03 +0300 Subject: [PATCH 3/5] Fix move operators pass --- .../MoveOperators/move_operators.cpp | 871 ++++++------------ 1 file changed, 304 insertions(+), 567 deletions(-) diff --git a/src/Transformations/MoveOperators/move_operators.cpp b/src/Transformations/MoveOperators/move_operators.cpp index bc9b1e5..234c3c0 100644 --- a/src/Transformations/MoveOperators/move_operators.cpp +++ b/src/Transformations/MoveOperators/move_operators.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "../../Utils/errors.h" #include "../../Utils/SgUtils.h" @@ -20,254 +21,124 @@ using namespace std; -set loop_tags = {FOR_NODE}; +set loop_tags = {FOR_NODE, WHILE_NODE, DO_WHILE_NODE}; set control_tags = {IF_NODE, ELSEIF_NODE, DO_WHILE_NODE, WHILE_NODE, LOGIF_NODE}; set control_end_tags = {CONTROL_END}; -namespace + +static bool isParentStmt(SgStatement* stmt, SgStatement* parent) { -enum class ArrayIndexCompareResult -{ - Equal, - NotEqual, - Unknown -}; - -// Structural key for array index / subscript analysis (stable across LOAD/STORE of the same access). -string buildStructuralExprKey(SgExpression* e) -{ - if (!e) - return string("_"); - - if (auto* ar = isSgArrayRefExp(e)) - { - SgSymbol* sym = ar->symbol() ? OriginalSymbol(ar->symbol()) : nullptr; - string key = string("A(") + (sym ? sym->identifier() : "?"); - const int n = ar->numberOfSubscripts(); - for (int i = 0; i < n; ++i) - { - key += ","; - key += buildStructuralExprKey(ar->subscript(i)); - } - key += ")"; - return key; - } - - if (e->variant() == VAR_REF || e->variant() == CONST_REF) - { - SgSymbol* sym = e->symbol() ? OriginalSymbol(e->symbol()) : nullptr; - return string((e->variant() == VAR_REF) ? "V(" : "C(") + (sym ? sym->identifier() : "?") + ")"; - } - - if (auto* v = isSgValueExp(e)) - { - if (e->variant() == INT_VAL) - return string("I(") + to_string(v->intValue()) + ")"; - if (e->variant() == BOOL_VAL) - return string("B(") + (v->boolValue() ? "1" : "0") + ")"; - if (e->variant() == CHAR_VAL) - return string("CH(") + string(1, v->charValue()) + ")"; - if (e->variant() == FLOAT_VAL) - { - char* fv = v->floatValue(); - return string("F(") + (fv ? string(fv) : string()) + ")"; - } - if (e->variant() == DOUBLE_VAL) - { - char* dv = v->doubleValue(); - if (!dv || !*dv) - return string("D()"); - char* endp = nullptr; - const double d = strtod(dv, &endp); - if (endp != dv && std::isfinite(d)) - { - const double r = std::round(d); - if (std::fabs(d - r) < 1e-12 && r >= static_cast(INT_MIN) && r <= static_cast(INT_MAX)) - return string("I(") + to_string(static_cast(r)) + ")"; - } - return string("D(") + string(dv) + ")"; - } - if (e->variant() == STRING_VAL) - return string("S(") + (v->stringValue() ? v->stringValue() : string()) + ")"; - } - - if (e->variant() == MULT_OP && e->lhs() && e->rhs()) - { - string a = buildStructuralExprKey(e->lhs()); - string b = buildStructuralExprKey(e->rhs()); - if (a > b) - swap(a, b); - return string("N(") + to_string(e->variant()) + ",L=" + a + ",R=" + b + ")"; - } - - string key = string("N(") + to_string(e->variant()); - if (e->lhs()) - key += ",L=" + buildStructuralExprKey(e->lhs()); - if (e->rhs()) - key += ",R=" + buildStructuralExprKey(e->rhs()); - key += ")"; - return key; + for (; stmt; stmt = stmt->controlParent()) + if (stmt == parent) + return true; + return false; } -// Prefer AST from IR instruction (same SgArrayRef for matching store/load); fallback to idxStack string. -string memexKeyForArrayLoadStore(const SAPFOR::Instruction* instr, const function& irStackKey) +static bool isStatementInFile(SgStatement* st, const string& fileName) { - if (!instr) - return string(); - SgExpression* ex = instr->getExpression(); - if (ex) - { - if (isSgArrayRefExp(ex)) - return string("MEMEX#") + buildStructuralExprKey(ex); - return string("MEMEX#") + buildStructuralExprKey(ex); - } - return irStackKey(); -} - -ArrayIndexCompareResult compareIndexExpressions(SgExpression* a, SgExpression* b) -{ - if (!a && !b) - return ArrayIndexCompareResult::Equal; - if (!a || !b) - return ArrayIndexCompareResult::NotEqual; - const string ka = buildStructuralExprKey(a); - const string kb = buildStructuralExprKey(b); - if (ka.empty() || kb.empty()) - return ArrayIndexCompareResult::Unknown; - if (ka == kb) - return ArrayIndexCompareResult::Equal; - return ArrayIndexCompareResult::NotEqual; -} - -ArrayIndexCompareResult compareArrayRefExpressions(SgArrayRefExp* a, SgArrayRefExp* b) -{ - if (!a && !b) - return ArrayIndexCompareResult::Equal; - if (!a || !b) - return ArrayIndexCompareResult::NotEqual; - SgSymbol* s1 = a->symbol() ? OriginalSymbol(a->symbol()) : nullptr; - SgSymbol* s2 = b->symbol() ? OriginalSymbol(b->symbol()) : nullptr; - if (s1 && s2) - { - if (strcmp(s1->identifier(), s2->identifier()) != 0) - return ArrayIndexCompareResult::NotEqual; - } - else if (s1 != s2) - return ArrayIndexCompareResult::NotEqual; - if (a->numberOfSubscripts() != b->numberOfSubscripts()) - return ArrayIndexCompareResult::NotEqual; - for (int i = 0; i < a->numberOfSubscripts(); ++i) - { - ArrayIndexCompareResult c = compareIndexExpressions(a->subscript(i), b->subscript(i)); - if (c != ArrayIndexCompareResult::Equal) - return c; - } - return ArrayIndexCompareResult::Equal; -} -} // namespace - -static vector findInstructionsFromStatement(SgStatement* st, const vector& blocks) -{ - vector result; if (!st) - return result; + return false; - const int stmtId = st->id(); - for (auto* bb : blocks) + const char* stmtFile = st->fileName(); + return stmtFile && fileName == stmtFile; +} + +static vector findLoopStatementsInFunction(SgStatement* funcStmt, const string& fileName) +{ + vector loops; + if (!funcStmt) + return loops; + + SgStatement* lastNode = funcStmt->lastNodeOfStmt(); + for (SgStatement* st = funcStmt; st && st != lastNode; st = st->lexNext()) + if (loop_tags.count(st->variant()) && isStatementInFile(st, fileName)) + loops.push_back(st); + + return loops; +} + +static SgStatement* firstSignificantOperatorInBlock(const SAPFOR::BasicBlock* bb, const string& fileName) +{ + if (!bb) + return nullptr; + + for (auto* ir : bb->getInstructions()) { - if (!bb) + if (!ir || !ir->getInstruction()) continue; - for (auto* ir : bb->getInstructions()) - { - if (!ir || !ir->getInstruction()) - continue; - - SgStatement* op = ir->getInstruction()->getOperator(); - if (op && op->id() == stmtId) - result.push_back(ir); - } + SgStatement* st = ir->getInstruction()->getOperator(); + if (isStatementInFile(st, fileName)) + return st; } - sort(result.begin(), result.end(), - [](const SAPFOR::IR_Block* a, const SAPFOR::IR_Block* b) { return a->getNumber() < b->getNumber(); }); - return result; + return nullptr; } -vector findFuncBlocksByFuncStatement(SgStatement *st, const map>& FullIR) { - vector result; - if (!st) - return result; +static SgStatement* lastSignificantOperatorInBlock(const SAPFOR::BasicBlock* bb, const string& fileName) +{ + if (!bb) + return nullptr; - Statement* forSt = (Statement*)st; - const string stmtFile = st->fileName(); - const int stmtLine = st->lineNumber(); - - for (auto& func: FullIR) { - if (!func.first || !func.first->funcPointer) + const auto& instructions = bb->getInstructions(); + for (auto it = instructions.rbegin(); it != instructions.rend(); ++it) + { + auto* ir = *it; + if (!ir || !ir->getInstruction()) continue; - const string funcFile = func.first->fileName; - const int funcLine = func.first->funcPointer->lineNumber(); - - // Important: select CFG blocks only for the same file and function header. - if (funcFile == stmtFile && funcLine == stmtLine) - { - result = func.second; - break; - } + SgStatement* st = ir->getInstruction()->getOperator(); + if (isStatementInFile(st, fileName)) + return st; } - return result; + + return nullptr; } -map> findAndAnalyzeLoops(SgStatement *st, const vector& blocks) { - map> result; - SgStatement *lastNode = st->lastNodeOfStmt(); - - while (st && st != lastNode) { - if (loop_tags.find(st -> variant()) != loop_tags.end()) { - SgForStmt *forSt = (SgForStmt*)st; - SgStatement *loopBody = forSt -> body(); - SgStatement *lastLoopNode = st->lastNodeOfStmt(); - set blocks_nums; - - while (loopBody && loopBody != lastLoopNode) { - vector irBlocks = findInstructionsFromStatement(loopBody, blocks); - if (!irBlocks.empty()) { - SAPFOR::IR_Block* IR = irBlocks.front(); - if (IR && IR->getBasicBlock()) { - if (blocks_nums.find(IR -> getBasicBlock() -> getNumber()) == blocks_nums.end()) { - result[forSt].push_back(IR -> getBasicBlock()); - blocks_nums.insert(IR -> getBasicBlock() -> getNumber()); - } - } - } - loopBody = loopBody -> lexNext(); - } - sort(result[forSt].begin(), result[forSt].end()); - } - st = st -> lexNext(); - } - return result; +static bool isBasicBlockInAnyLoop(const SAPFOR::BasicBlock* bb, const vector& loops, const string& fileName) +{ + SgStatement* first = firstSignificantOperatorInBlock(bb, fileName); + SgStatement* last = lastSignificantOperatorInBlock(bb, fileName); + if (!first || !last) + return false; + + + + for (auto* loop : loops) + if (loop && isParentStmt(first, loop) && isParentStmt(last, loop)) + return true; + + return false; } - -vector findBlocksInLoopsByFullIR( - SgStatement* funcStmt, +static vector findBlocksInLoopsByFullIR( + SgFile* file, const map>& FullIR) { vector result; - if (!funcStmt) + if (!file || !file->filename()) return result; - const vector funcBlocks = findFuncBlocksByFuncStatement(funcStmt, FullIR); - const auto loopsMapping = findAndAnalyzeLoops(funcStmt, funcBlocks); - + const string fileName = file->filename(); set uniq; - for (const auto& kv : loopsMapping) - for (auto* bb : kv.second) - if (bb) + + for (const auto& func : FullIR) + { + FuncInfo* funcInfo = func.first; + if (!funcInfo || !funcInfo->funcPointer) + continue; + + if (funcInfo->fileName != fileName) + continue; + + const vector loops = findLoopStatementsInFunction(funcInfo->funcPointer, fileName); + if (loops.empty()) + continue; + + for (auto* bb : func.second) + if (isBasicBlockInAnyLoop(bb, loops, fileName)) uniq.insert(bb); + } result.assign(uniq.begin(), uniq.end()); sort(result.begin(), result.end(), @@ -281,11 +152,10 @@ vector findBlocksInLoopsByFullIR( return result; } -static map> analyzeBasicBlockIntraDependencies(const SAPFOR::BasicBlock* bb) +static map> analyzeBasicBlockIntraDependencies(const SAPFOR::BasicBlock* bb) { - map> result; if (!bb) - return result; + return {}; auto isCompoundStmt = [](SgStatement* st) -> bool { @@ -295,306 +165,193 @@ static map> analyzeBasicBlockIntraDependencie return loop_tags.count(v) || control_tags.count(v) || control_end_tags.count(v); }; - auto isVarArg = [](const SAPFOR::Argument* a) -> bool + auto normalizeSageString = [](const string& src) -> string { - return a && a->getType() == SAPFOR::CFG_ARG_TYPE::VAR; + string normalized; + bool prevSpace = false; + + for (char ch : src) + { + const bool isSpace = std::isspace(static_cast(ch)); + if (isSpace) + { + if (!normalized.empty()) + prevSpace = true; + continue; + } + + if (prevSpace && !normalized.empty()) + normalized += ' '; + normalized += ch; + prevSpace = false; + } + + return normalized; }; - auto isArrayArg = [](const SAPFOR::Argument* a) -> bool + auto sageExprToString = [&](SgExpression* expr) -> string { - return a && a->getType() == SAPFOR::CFG_ARG_TYPE::ARRAY; - }; - - auto varKey = [&](const SAPFOR::Argument* a) -> string - { - if (!a) + if (!expr) return string(); - return a->getValue(); + + char* raw = expr->unparse(); + return normalizeSageString(raw ? string(raw) : string()); }; - auto parseIntConst = [](const SAPFOR::Argument* a, int& out) -> bool + auto arrayElementKey = [&](SgArrayRefExp* arrayRef) -> string { - if (!a || a->getType() != SAPFOR::CFG_ARG_TYPE::CONST) - return false; - try + if (!arrayRef) + return string(); + + string key; + SgSymbol* sym = arrayRef->symbol() ? OriginalSymbol(arrayRef->symbol()) : nullptr; + if (sym && sym->identifier()) + key = sym->identifier(); + else + return sageExprToString(arrayRef); + + if (key.empty()) + return string(); + + key += "("; + for (int i = 0; i < arrayRef->numberOfSubscripts(); ++i) { - out = stoi(a->getValue()); - return true; + if (i) + key += ", "; + key += sageExprToString(arrayRef->subscript(i)); } - catch (...) + key += ")"; + + return key; + }; + + function&)> collectUsedKeysFromExpression = + [&](SgExpression* expr, set& usedKeys) + { + if (!expr) + return; + + if (isSgValueExp(expr) || expr->variant() == CONST_REF) + return; + + if (auto* arrayRef = isSgArrayRefExp(expr)) { - return false; + const string key = arrayElementKey(arrayRef); + if (!key.empty()) + usedKeys.insert(key); + + for (int i = 0; i < arrayRef->numberOfSubscripts(); ++i) + collectUsedKeysFromExpression(arrayRef->subscript(i), usedKeys); + return; + } + + if (auto* call = isSgFunctionCallExp(expr)) + { + for (int i = 0; i < call->numberOfArgs(); ++i) + collectUsedKeysFromExpression(call->arg(i), usedKeys); + return; + } + + if (expr->variant() == VAR_REF) + { + SgSymbol* sym = expr->symbol() ? OriginalSymbol(expr->symbol()) : nullptr; + if (sym && sym->identifier()) + usedKeys.insert(sym->identifier()); + return; + } + + collectUsedKeysFromExpression(expr->lhs(), usedKeys); + collectUsedKeysFromExpression(expr->rhs(), usedKeys); + }; + + auto collectUsedKeysFromArraySubscripts = [&](SgArrayRefExp* arrayRef, set& usedKeys) + { + if (!arrayRef) + return; + + for (int i = 0; i < arrayRef->numberOfSubscripts(); ++i) + collectUsedKeysFromExpression(arrayRef->subscript(i), usedKeys); + }; + + auto addOperatorDependencies = [&](SgStatement* stmt, + const set& usedKeys, + const map& varDeclarations, + map>& operatorsDependencies) + { + if (!stmt) + return; + + for (const string& key : usedKeys) + { + auto it = varDeclarations.find(key); + if (it != varDeclarations.end() && it->second && it->second != stmt) + operatorsDependencies[stmt].insert(it->second); } }; - auto isBarrierInstr = [&](const SAPFOR::Instruction* instr) -> bool + auto declarationKeyFromLeftPart = [&](SgStatement* stmt) -> string { - if (!instr) - return true; - const auto op = instr->getOperation(); - switch (op) + if (!stmt || stmt->variant() != ASSIGN_STAT) + return string(); + + SgExpression* lhs = stmt->expr(0); + if (!lhs) + return string(); + + if (auto* arrayRef = isSgArrayRefExp(lhs)) + return arrayElementKey(arrayRef); + + if (lhs->variant() == VAR_REF) { - case SAPFOR::CFG_OP::F_CALL: - case SAPFOR::CFG_OP::IO_PARAM: - case SAPFOR::CFG_OP::DVM_DIR: - case SAPFOR::CFG_OP::SPF_DIR: - case SAPFOR::CFG_OP::POINTER_ASS: - case SAPFOR::CFG_OP::EXIT: - return true; - default: - return false; + SgSymbol* sym = lhs->symbol() ? OriginalSymbol(lhs->symbol()) : nullptr; + if (sym && sym->identifier()) + return sym->identifier(); } + + return string(); }; - map lastDef; - map lastMemDef; - map> depsSets; + vector operatorsOrder; + set seenOperators; - const auto& irs = bb->getInstructions(); - size_t i = 0; - while (i < irs.size()) + for (auto* ir : bb->getInstructions()) { - auto* ir = irs[i]; if (!ir || !ir->getInstruction()) - { - ++i; continue; - } - const SAPFOR::Instruction* firstInstr = ir->getInstruction(); - SgStatement* stmt = firstInstr->getOperator(); + const SAPFOR::Instruction* instr = ir->getInstruction(); + SgStatement* stmt = instr->getOperator(); if (!stmt || isCompoundStmt(stmt)) - { - ++i; continue; - } - vector group; - group.reserve(8); - bool isBarrierStmt = false; - - while (i < irs.size()) - { - auto* ir2 = irs[i]; - if (!ir2 || !ir2->getInstruction()) - { - ++i; - continue; - } - - const SAPFOR::Instruction* instr = ir2->getInstruction(); - if (instr->getOperator() != stmt) - break; - - group.push_back(instr); - if (isBarrierInstr(instr)) - isBarrierStmt = true; - ++i; - } - - if (!result.count(stmt)) - result[stmt] = {}; - - set usesVars; - set defsVars; - set usesMem; - set defsMem; - - vector idxStack; - idxStack.reserve(8); - - auto idxAtom = [&](const SAPFOR::Argument* a) -> string - { - if (!a) - return string(); - const auto t = a->getType(); - if (t == SAPFOR::CFG_ARG_TYPE::VAR || t == SAPFOR::CFG_ARG_TYPE::CONST || t == SAPFOR::CFG_ARG_TYPE::CONST_STR) - return a->getValue(); - return string("*"); - }; - - auto joinIdx = [&](const vector& idx) -> string - { - string s; - for (size_t k = 0; k < idx.size(); ++k) - { - if (k) - s += ","; - s += idx[k]; - } - return s; - }; - - auto popLastIdx = [&](int cnt) -> vector - { - vector idx; - if (cnt <= 0 || (size_t)cnt > idxStack.size()) - return idx; - idx.assign(idxStack.end() - cnt, idxStack.end()); - idxStack.erase(idxStack.end() - cnt, idxStack.end()); - return idx; - }; - - auto memKeyFromLoadStore = [&](const SAPFOR::Instruction* instr) -> string - { - if (!instr) - return string(); - SAPFOR::Argument* base = instr->getArg1(); - if (!isArrayArg(base)) - return string(); - - int cnt = 0; - if (!parseIntConst(instr->getArg2(), cnt)) - cnt = 0; - const auto idx = popLastIdx(cnt); - return base->getValue() + "[" + joinIdx(idx) + "]"; - }; - - string lastStoreKey; - string lastScalarDefKey; - - for (auto* instr : group) - { - if (!instr) - continue; - - if (isVarArg(instr->getArg1())) - usesVars.insert(varKey(instr->getArg1())); - if (isVarArg(instr->getArg2())) - usesVars.insert(varKey(instr->getArg2())); - - if (instr->getOperation() == SAPFOR::CFG_OP::RANGE && isVarArg(instr->getResult())) - usesVars.insert(varKey(instr->getResult())); - - if ((instr->getOperation() == SAPFOR::CFG_OP::STORE || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE) && - isVarArg(instr->getResult())) - { - usesVars.insert(varKey(instr->getResult())); - } - - if (instr->getOperation() == SAPFOR::CFG_OP::REF) - { - idxStack.push_back(idxAtom(instr->getArg1())); - } - else if (instr->getOperation() == SAPFOR::CFG_OP::RANGE) - { - idxStack.push_back(idxAtom(instr->getArg1()) + ":" + idxAtom(instr->getArg2()) + ":" + idxAtom(instr->getResult())); - } - else if (instr->getOperation() == SAPFOR::CFG_OP::LOAD || instr->getOperation() == SAPFOR::CFG_OP::STORE) - { - int dimCnt = 0; - if (!parseIntConst(instr->getArg2(), dimCnt)) - dimCnt = 0; - - string k; - if (instr->getExpression()) - { - k = memexKeyForArrayLoadStore(instr, []() { return string(); }); - if (!k.empty()) - popLastIdx(dimCnt); - } - if (k.empty()) - k = memKeyFromLoadStore(instr); - - if (!k.empty()) - { - if (instr->getOperation() == SAPFOR::CFG_OP::LOAD) - usesMem.insert(k); - else - { - defsMem.insert(k); - lastStoreKey = k; - } - } - } - else if (instr->getOperation() == SAPFOR::CFG_OP::REC_REF_LOAD || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE) - { - SAPFOR::Argument* base = instr->getArg1(); - if (base && (base->getType() == SAPFOR::CFG_ARG_TYPE::RECORD || base->getType() == SAPFOR::CFG_ARG_TYPE::VAR)) - { - const string k = base->getValue(); - if (instr->getOperation() == SAPFOR::CFG_OP::REC_REF_LOAD) - usesMem.insert(k); - else - { - defsMem.insert(k); - lastStoreKey = k; - } - } - } - } - - if (!group.empty()) - { - const SAPFOR::Instruction* last = group.back(); - if (last && last->getOperation() == SAPFOR::CFG_OP::ASSIGN && isVarArg(last->getResult())) - { - lastScalarDefKey = varKey(last->getResult()); - defsVars.insert(lastScalarDefKey); - } - else if (last && (last->getOperation() == SAPFOR::CFG_OP::STORE || last->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE)) - { - if (!lastStoreKey.empty()) - defsMem.insert(lastStoreKey); - } - } - - auto addDepFromMap = [&](const map& m, const string& k) - { - auto it = m.find(k); - if (it == m.end()) - return; - if (it->second && it->second != stmt) - depsSets[stmt].insert(it->second); - }; - - for (const auto& k : usesVars) - addDepFromMap(lastDef, k); - for (const auto& k : usesMem) - addDepFromMap(lastMemDef, k); - - if (isBarrierStmt) - { - lastDef.clear(); - lastMemDef.clear(); - continue; - } - - for (const auto& k : defsVars) - { - addDepFromMap(lastDef, k); - lastDef[k] = stmt; - } - for (const auto& k : defsMem) - { - addDepFromMap(lastMemDef, k); - lastMemDef[k] = stmt; - } + if (seenOperators.insert(stmt).second) + operatorsOrder.push_back(stmt); } - for (auto& kv : result) + map varDeclarations; + map> operatorsDependencies; + + for (SgStatement* stmt : operatorsOrder) { - SgStatement* op = kv.first; - auto it = depsSets.find(op); - if (it == depsSets.end()) - continue; + set usedKeys; + if (stmt) + { + collectUsedKeysFromExpression(stmt->expr(1), usedKeys); + collectUsedKeysFromArraySubscripts(isSgArrayRefExp(stmt->expr(0)), usedKeys); + } + addOperatorDependencies(stmt, usedKeys, varDeclarations, operatorsDependencies); - kv.second.assign(it->second.begin(), it->second.end()); - sort(kv.second.begin(), kv.second.end(), - [](SgStatement* a, SgStatement* b) - { - const int la = a ? a->lineNumber() : -1; - const int lb = b ? b->lineNumber() : -1; - if (la != lb) - return la < lb; - return a < b; - }); + const string declarationKey = declarationKeyFromLeftPart(stmt); + if (!declarationKey.empty()) + varDeclarations[declarationKey] = stmt; } - return result; + return operatorsDependencies; } -static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb, const char* expectedFile) +static bool reorderOperatorsInBasicBlockUsingDeps( + SAPFOR::BasicBlock* bb, + const map>& operatorsDependencies) { if (!bb) return false; @@ -624,18 +381,6 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb, const if (ops.size() < 2) return false; - // Check that analyzed BB is in the same file as the expected file - const char* bbFile = ops.front()->fileName(); - if (!bbFile) - bbFile = "(unknown)"; - if (expectedFile && strcmp(expectedFile, bbFile) != 0) - return false; - for (auto* st : ops) - { - if (!st || !st->fileName() || strcmp(st->fileName(), bbFile) != 0) - return false; - } - SgStatement* parent = ops.front()->controlParent(); if (!parent) return false; @@ -683,76 +428,72 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb, const return false; } - // Compute dependencies (inside BB) and build a new order by moving each statement - // as close as possible after its last dependency (if any). - const auto depsMap = analyzeBasicBlockIntraDependencies(bb); - vector order = ops; - const vector originalOrder = ops; - const int nOrig = (int)originalOrder.size(); + map originalIndex; + for (int i = 0; i < (int)ops.size(); ++i) + originalIndex[ops[i]] = i; - auto indexIn = [](const vector& v, SgStatement* s) -> int - { - for (int i = 0; i < (int)v.size(); ++i) - if (v[i] == s) - return i; - return -1; - }; + map> moveAfter; + set moved; - auto indexInOriginal = [&](SgStatement* s) -> int + for (SgStatement* st : ops) { - return indexIn(originalOrder, s); - }; - - for (SgStatement* s : ops) - { - auto itDeps = depsMap.find(s); - if (itDeps == depsMap.end() || itDeps->second.empty()) + auto itDeps = operatorsDependencies.find(st); + if (itDeps == operatorsDependencies.end() || itDeps->second.empty()) continue; - int lastDepOrigIdx = -1; + SgStatement* lastDep = nullptr; + int lastDepIdx = -1; for (SgStatement* dep : itDeps->second) { - const int j = indexInOriginal(dep); - if (j >= 0) - lastDepOrigIdx = max(lastDepOrigIdx, j); + auto itIdx = originalIndex.find(dep); + if (itIdx != originalIndex.end() && itIdx->second > lastDepIdx) + { + lastDep = dep; + lastDepIdx = itIdx->second; + } } - if (lastDepOrigIdx < 0) + if (!lastDep || lastDep == st) continue; - SgStatement* successor = nullptr; - if (lastDepOrigIdx + 1 < nOrig) - successor = originalOrder[lastDepOrigIdx + 1]; - - int posS = indexIn(order, s); - if (posS < 0) - continue; - - if (successor == nullptr) - { - if (posS == (int)order.size() - 1) - continue; - order.erase(order.begin() + posS); - order.push_back(s); - continue; - } - - if (successor == s) - continue; - - const int posSucc = indexIn(order, successor); - if (posSucc < 0) - continue; - - if (posS + 1 == posSucc) - continue; - - order.erase(order.begin() + posS); - const int posSucc2 = indexIn(order, successor); - if (posSucc2 < 0) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - order.insert(order.begin() + posSucc2, s); + moveAfter[lastDep].push_back(st); + moved.insert(st); } + vector order; + order.reserve(ops.size()); + set emitted; + set active; + bool invalidOrder = false; + + function emitStatement = [&](SgStatement* st) + { + if (!st || invalidOrder || emitted.count(st)) + return; + if (active.count(st)) + { + invalidOrder = true; + return; + } + + active.insert(st); + emitted.insert(st); + order.push_back(st); + + auto itMovedAfter = moveAfter.find(st); + if (itMovedAfter != moveAfter.end()) + for (SgStatement* dependent : itMovedAfter->second) + emitStatement(dependent); + + active.erase(st); + }; + + for (SgStatement* st : ops) + if (!moved.count(st)) + emitStatement(st); + + if (invalidOrder || order.size() != ops.size()) + return false; + bool changed = false; for (size_t i = 0; i < ops.size(); ++i) if (ops[i] != order[i]) @@ -826,18 +567,14 @@ void moveOperators(SgFile* file, const mapfilename()) == -1) printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - const int funcNum = file->numberOfFunctions(); - for (int i = 0; i < funcNum; ++i) - { - SgStatement* st = file->functions(i); + const auto loopBlocks = findBlocksInLoopsByFullIR(file, FullIR); - const auto loopBlocks = findBlocksInLoopsByFullIR(st, FullIR); - for (auto* bb : loopBlocks) - { - if (!bb) - continue; - if (reorderOperatorsInBasicBlockUsingDeps(bb, file->filename())) - countOfTransform += 1; - } + for (auto* bb : loopBlocks) + { + if (!bb) + continue; + const auto operatorsDependencies = analyzeBasicBlockIntraDependencies(bb); + if (reorderOperatorsInBasicBlockUsingDeps(bb, operatorsDependencies)) + countOfTransform += 1; } } -- 2.49.1 From 3465feca351c18696a2fdd15f3272151cb15ee9d Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Tue, 5 May 2026 16:47:31 +0300 Subject: [PATCH 4/5] remove redundant --- src/Transformations/MoveOperators/move_operators.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/Transformations/MoveOperators/move_operators.cpp b/src/Transformations/MoveOperators/move_operators.cpp index 234c3c0..686cbd3 100644 --- a/src/Transformations/MoveOperators/move_operators.cpp +++ b/src/Transformations/MoveOperators/move_operators.cpp @@ -5,18 +5,14 @@ #include #include #include -#include -#include #include #include #include "../../Utils/errors.h" #include "../../Utils/SgUtils.h" #include "../../GraphCall/graph_calls.h" -#include "../../GraphCall/graph_calls_func.h" #include "../../CFGraph/CFGraph.h" #include "../../CFGraph/IR.h" -#include "../../GraphLoop/graph_loops.h" #include "move_operators.h" using namespace std; @@ -102,8 +98,6 @@ static bool isBasicBlockInAnyLoop(const SAPFOR::BasicBlock* bb, const vector Date: Tue, 5 May 2026 17:57:29 +0300 Subject: [PATCH 5/5] updated version and dvm --- projects/dvm | 2 +- src/Utils/version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/dvm b/projects/dvm index ab99430..271ca65 160000 --- a/projects/dvm +++ b/projects/dvm @@ -1 +1 @@ -Subproject commit ab99430aeedc2ac943e7f41d38abb6e6393ed2f4 +Subproject commit 271ca656fd1547501619d3f4776d83e2a38e63de diff --git a/src/Utils/version.h b/src/Utils/version.h index 05ba3d0..207a063 100644 --- a/src/Utils/version.h +++ b/src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2472" +#define VERSION_SPF "2473" -- 2.49.1