From fba78c7184c75b422ee7d539c2b5b32ce9c69403 Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Wed, 6 May 2026 00:45:37 +0300 Subject: [PATCH 1/3] Associativity for MULT_OP and ADD_OP for array indices --- .../MoveOperators/move_operators.cpp | 91 ++++++++++++++++++- 1 file changed, 89 insertions(+), 2 deletions(-) diff --git a/src/Transformations/MoveOperators/move_operators.cpp b/src/Transformations/MoveOperators/move_operators.cpp index 686cbd3..be51ce1 100644 --- a/src/Transformations/MoveOperators/move_operators.cpp +++ b/src/Transformations/MoveOperators/move_operators.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #include #include @@ -192,6 +191,94 @@ static map> analyzeBasicBlockIntraDependencies(c return normalizeSageString(raw ? string(raw) : string()); }; + function canonicalExprKey; + canonicalExprKey = [&](SgExpression* expr) -> string + { + if (!expr) + return string(); + + const int v = expr->variant(); + + if (v == ADD_OP) + { + vector terms; + function flattenAdd = [&](SgExpression* e) + { + if (!e) + return; + if (e->variant() == ADD_OP) + { + flattenAdd(e->lhs()); + flattenAdd(e->rhs()); + } + else + terms.push_back(canonicalExprKey(e)); + }; + flattenAdd(expr); + sort(terms.begin(), terms.end()); + string joined; + for (size_t i = 0; i < terms.size(); ++i) + { + if (i) + joined += " + "; + joined += terms[i]; + } + return joined; + } + + if (v == MULT_OP) + { + vector factors; + function flattenMult = [&](SgExpression* e) + { + if (!e) + return; + if (e->variant() == MULT_OP) + { + flattenMult(e->lhs()); + flattenMult(e->rhs()); + } + else + factors.push_back(canonicalExprKey(e)); + }; + flattenMult(expr); + sort(factors.begin(), factors.end()); + string joined; + for (size_t i = 0; i < factors.size(); ++i) + { + if (i) + joined += " * "; + joined += factors[i]; + } + return joined; + } + + SgExpression *l = expr->lhs(); + SgExpression *r = expr->rhs(); + + if (l && r) + { + if (v == SUBT_OP || v == SUB_OP) + return canonicalExprKey(l) + string(" - ") + canonicalExprKey(r); + if (v == DIV_OP || v == INTEGER_DIV_OP) + return canonicalExprKey(l) + string(" / ") + canonicalExprKey(r); + if (v == EXP_OP) + return canonicalExprKey(l) + string(" ** ") + canonicalExprKey(r); + } + + if (l && !r) + { + if (v == MINUS_OP) + return string("-") + canonicalExprKey(l); + if (v == UNARY_ADD_OP) + return canonicalExprKey(l); + if (v == CAST_OP) + return canonicalExprKey(l); + } + + return sageExprToString(expr); + }; + auto arrayElementKey = [&](SgArrayRefExp* arrayRef) -> string { if (!arrayRef) @@ -212,7 +299,7 @@ static map> analyzeBasicBlockIntraDependencies(c { if (i) key += ", "; - key += sageExprToString(arrayRef->subscript(i)); + key += canonicalExprKey(arrayRef->subscript(i)); } key += ")"; From 583fe7775ec67a8844eeca9533c3bb91beafe478 Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Wed, 6 May 2026 03:45:25 +0300 Subject: [PATCH 2/3] Add dependency between reading and writing var value --- .../MoveOperators/move_operators.cpp | 47 ++++++++++++------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/src/Transformations/MoveOperators/move_operators.cpp b/src/Transformations/MoveOperators/move_operators.cpp index be51ce1..a92ece2 100644 --- a/src/Transformations/MoveOperators/move_operators.cpp +++ b/src/Transformations/MoveOperators/move_operators.cpp @@ -354,22 +354,6 @@ static map> analyzeBasicBlockIntraDependencies(c 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 declarationKeyFromLeftPart = [&](SgStatement* stmt) -> string { if (!stmt || stmt->variant() != ASSIGN_STAT) @@ -392,6 +376,31 @@ static map> analyzeBasicBlockIntraDependencies(c return string(); }; + auto addOperatorDependencies = [&](SgStatement* stmt, + const set& usedKeys, + const map& varDeclarations, + const map& varUsages, + 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); + } + + const string defKey = declarationKeyFromLeftPart(stmt); + if (!defKey.empty()) + { + auto itu = varUsages.find(defKey); + if (itu != varUsages.end() && itu->second && itu->second != stmt) + operatorsDependencies[stmt].insert(itu->second); + } + }; + vector operatorsOrder; set seenOperators; @@ -410,6 +419,7 @@ static map> analyzeBasicBlockIntraDependencies(c } map varDeclarations; + map varUsages; map> operatorsDependencies; for (SgStatement* stmt : operatorsOrder) @@ -420,11 +430,14 @@ static map> analyzeBasicBlockIntraDependencies(c collectUsedKeysFromExpression(stmt->expr(1), usedKeys); collectUsedKeysFromArraySubscripts(isSgArrayRefExp(stmt->expr(0)), usedKeys); } - addOperatorDependencies(stmt, usedKeys, varDeclarations, operatorsDependencies); + addOperatorDependencies(stmt, usedKeys, varDeclarations, varUsages, operatorsDependencies); const string declarationKey = declarationKeyFromLeftPart(stmt); if (!declarationKey.empty()) varDeclarations[declarationKey] = stmt; + + for (const string& key : usedKeys) + varUsages[key] = stmt; } return operatorsDependencies; From e5fa184fe0bae02822ab3374a3aaa2f513031193 Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Wed, 6 May 2026 12:14:32 +0300 Subject: [PATCH 3/3] fix reordering --- .../MoveOperators/move_operators.cpp | 92 ++++++++----------- 1 file changed, 37 insertions(+), 55 deletions(-) diff --git a/src/Transformations/MoveOperators/move_operators.cpp b/src/Transformations/MoveOperators/move_operators.cpp index a92ece2..ec468b5 100644 --- a/src/Transformations/MoveOperators/move_operators.cpp +++ b/src/Transformations/MoveOperators/move_operators.cpp @@ -522,72 +522,54 @@ static bool reorderOperatorsInBasicBlockUsingDeps( return false; } - map originalIndex; + map newIndex; + map movesCount; + vector order = ops; for (int i = 0; i < (int)ops.size(); ++i) - originalIndex[ops[i]] = i; - - map> moveAfter; - set moved; + { + newIndex[ops[i]] = i; + movesCount[ops[i]] = 0; + } for (SgStatement* st : ops) { auto itDeps = operatorsDependencies.find(st); - if (itDeps == operatorsDependencies.end() || itDeps->second.empty()) - continue; - - SgStatement* lastDep = nullptr; - int lastDepIdx = -1; - for (SgStatement* dep : itDeps->second) + if (itDeps != operatorsDependencies.end() && !itDeps->second.empty()) { - auto itIdx = originalIndex.find(dep); - if (itIdx != originalIndex.end() && itIdx->second > lastDepIdx) + SgStatement* lastDep = nullptr; + int lastDepIdx = -1; + for (SgStatement* dep : itDeps->second) { - lastDep = dep; - lastDepIdx = itIdx->second; + auto itIdx = newIndex.find(dep); + if (itIdx != newIndex.end() && itIdx->second > lastDepIdx) + { + lastDep = dep; + lastDepIdx = itIdx->second; + } + } + if (lastDep && lastDep != st) + { + const int stPos = newIndex[st]; + const int ldPos = newIndex[lastDep]; + if (stPos > ldPos) + { + auto itSt = find(order.begin(), order.end(), st); + auto itLd = find(order.begin(), order.end(), lastDep); + if (itSt == order.end() || itLd == order.end()) + return false; + order.erase(itSt); + itLd = find(order.begin(), order.end(), lastDep); + if (itLd == order.end()) + return false; + order.insert(itLd + 1 + movesCount[lastDep], st); + for (int i = 0; i < (int)order.size(); ++i) + newIndex[order[i]] = i; + movesCount[lastDep] += 1; + } } } - if (!lastDep || lastDep == st) - continue; - - 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])